correct fix-point arithmetic

This commit is contained in:
Jörg Thalheim 2013-12-18 10:01:06 +01:00
parent 588ee8b710
commit df3750364a

40
sqrt.c
View File

@ -6,9 +6,12 @@
typedef uint32_t u32;
#define COMMA 12
#define COMMA_FIX (COMMA >> 1)
void heron_sqrt(u32 *mem) {
int i = mem[0];
while (i > 0) {
while (i >= 1) {
u32 s = mem[i];
if (s > 1) {
// x_0 = (s + 1) / 2
@ -24,23 +27,29 @@ void heron_sqrt(u32 *mem) {
}
old_x = x;
}
mem[i] = x;
mem[i] = x << COMMA_FIX;
}
i--;
}
}
int main() {
u32 data[] = {0,
float data[] = {
0,
1,
2,
4,
2.5,
2.25,
2.125,
2.0625,
2.03125, // precision test
3<<2,
1<<3,
1<<4,
1<<5,
1<<6,
5<<2,
11<<7,
1<<7,
1<<8,
1<<16,
@ -50,21 +59,26 @@ int main() {
1<<20, // 32 - 14 = 20
1<<24, // 32 - 8 = 24
1<<30,
0xffffffff};
const int length = sizeof(data)/sizeof(u32);
u32* mem = malloc(sizeof(data) + sizeof(u32));
memcpy(&mem[1], data, sizeof(data));
0xffffffff
};
const int length = sizeof(data)/sizeof(float);
int i;
u32* mem = malloc((length + 1) * sizeof(u32));
mem[0] = length;
for (i = 1; i <= length; i++) {
mem[i] = (u32) (data[i] * (1 << COMMA));
}
heron_sqrt(mem);
int i = 0;
for (i = 0; i < length; i++) {
printf("s = %u\n", data[i]);
if (data[i] < (0xfffffff >> (COMMA))) {
printf("s = %f\n", data[i]);
printf("sqrt(s) = %f\n", sqrt(data[i]));
printf("heron_sqrt(s) = %d\n", mem[i+1]);
printf("heron_sqrt(s) = %f\n", ((float) mem[i]) / (1 << COMMA));
}
puts("\n");
}
return 0;