first
This commit is contained in:
commit
7ea7968043
87
sqrt.c
Normal file
87
sqrt.c
Normal file
@ -0,0 +1,87 @@
|
|||||||
|
#include <stdio.h>
|
||||||
|
#include <math.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
/*
|
||||||
|
* s 1
|
||||||
|
* \ /
|
||||||
|
* +
|
||||||
|
* | 1
|
||||||
|
* \ /
|
||||||
|
* >>
|
||||||
|
* |
|
||||||
|
* s x
|
||||||
|
* \ / \
|
||||||
|
* (/) |\
|
||||||
|
* | | \
|
||||||
|
* \ / \
|
||||||
|
* + \
|
||||||
|
* | 1 |
|
||||||
|
* \ / |
|
||||||
|
* >> |
|
||||||
|
* | /
|
||||||
|
* \ /
|
||||||
|
* -
|
||||||
|
*/
|
||||||
|
typedef uint32_t u32;
|
||||||
|
|
||||||
|
u32 heron_sqrt(u32 s, int* iterations) {
|
||||||
|
// x_0 = (s + 1) / 2
|
||||||
|
// without increment to avoid overflow for 0xffffffff
|
||||||
|
u32 x = s >> 1;
|
||||||
|
u32 old_x = x;
|
||||||
|
|
||||||
|
*iterations = 0; // statistic
|
||||||
|
|
||||||
|
if (x == 0) return 0;
|
||||||
|
while(1) {
|
||||||
|
(*iterations)++; // statistic
|
||||||
|
// x_{n + 1} = (x_n + (s / x_n)) / 2
|
||||||
|
x = (x >> 1) + ((s/x) >> 1);
|
||||||
|
if (old_x <= x) {
|
||||||
|
return x;
|
||||||
|
}
|
||||||
|
old_x = x;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
u32 data[] = {0, 2, 4,
|
||||||
|
1<<2,
|
||||||
|
1<<3,
|
||||||
|
1<<4,
|
||||||
|
1<<5,
|
||||||
|
1<<6,
|
||||||
|
1<<7,
|
||||||
|
1<<8,
|
||||||
|
1<<16,
|
||||||
|
1<<17,
|
||||||
|
1<<18,
|
||||||
|
1<<19,
|
||||||
|
1<<20, // 32 - 14 = 20
|
||||||
|
1<<24, // 32 - 8 = 24
|
||||||
|
1<<30,
|
||||||
|
0xffffffff};
|
||||||
|
int iter = 0, i = 0;
|
||||||
|
for (i = 0; i < sizeof(data)/sizeof(int); i++) {
|
||||||
|
if (i != 0) printf("------\n");
|
||||||
|
printf("s = %u\n", data[i]);
|
||||||
|
|
||||||
|
printf("sqrt(s) = %f\n", sqrt(data[i]));
|
||||||
|
printf("heron_sqrt(s) = %d (%d iterations)\n",
|
||||||
|
heron_sqrt(data[i], &iter), iter);
|
||||||
|
|
||||||
|
// 1/16 = 0.0625
|
||||||
|
u32 s8 = data[i] << 8;
|
||||||
|
printf("heron_sqrt8(s) = %f (%d iterations)%s\n",
|
||||||
|
((double) heron_sqrt(s8, &iter)) / 16,
|
||||||
|
iter, s8 == 0 ? " Out of range!" : "");
|
||||||
|
|
||||||
|
// 1/128 = 0.0078125
|
||||||
|
u32 s14 = data[i] << 14;
|
||||||
|
printf("heron_sqrt14(s) = %f (%d iterations)%s\n",
|
||||||
|
((double) heron_sqrt(data[i]<<14, &iter)) / 128,
|
||||||
|
iter, s14 == 0 ? " Out of range!" : "");
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user