This commit is contained in:
Jörg Thalheim 2013-12-06 15:11:41 +01:00
parent 86396fbadb
commit 1d6367161d
2 changed files with 146 additions and 45 deletions

131
graph.dot Normal file
View File

@ -0,0 +1,131 @@
digraph heron {
//node [shape=circle,regular=1,style=filled,fillcolor=white];
edge [arrowhead=odot];
graph [overlap=false];
subgraph {
edge [weight=3];
C0 -> C1 -> C2 -> C3 -> C4 -> C5 -> C6 -> C7 -> C8 -> C9
}
// variables & constants
mem_0 [label="mem[0]"];
mem_i [label="mem[i]"];
mem_i2 [label="mem[i]"];
i [ ];
1 [ ];
"1a" [label="1" ];
"1b" [label="1" ];
"1c" [label="1" ];
"1d" [label="1" ];
Finish [label="Finish"];
// operands
s_shift_1 [label=">>",];
i_lte_mem_0 [label=">=",];
// i <= mem[0]
mem_0 -> i_lte_mem_0;
i -> i_lte_mem_0;
{ rank=same; C1; i_lte_mem_0; }
{ rank=same; C0; i; mem_0;}
// if (i <= mem[0]) ->
i_lte_mem_0 -> mem_s_gte_1 [style=dotted, arrowhead=normal,label="True",lhead=cluster_i_lte_mem_0];
// else
i_lte_mem_0 -> Finish [style=dotted, arrowhead=normal,label="False",lhead=cluster_i_lte_mem_0];
{ rank=same; C9; Finish;}
subgraph i_lte_mem_0 {
mem_s_gte_1 [label=">"];
s_div_x [label="/",];
new_x [label="+",];
s_div_x_shift_1 [label=">>",];
x_shift_1 [label=">>",];
old_x_lte_new_x [label="¹>=",];
inc_i [label="+",];
// (s > 1)
mem_i -> mem_s_gte_1;
"1d" -> mem_s_gte_1;
{ rank=same; C2; mem_s_gte_1}
// if (s > 1)
mem_s_gte_1 -> s_shift_1 [style=dotted,arrowhead=normal,label="True"];
// else
mem_s_gte_1 -> inc_i [style=dotted,arrowhead=normal,label="False"];
subgraph if_mem_i_gte_1 {
// x = s >> 1
mem_i -> s_shift_1;
1 -> s_shift_1;
s_shift_1 -> x;
{ rank=same; C3; s_shift_1; x}
// (x >> 1)
x -> x_shift_1;
"1a" -> x_shift_1;
// (s/x)
mem_i -> s_div_x;
x -> s_div_x;
{ rank=same; C4; x_shift_1; s_div_x}
// ((s/x) >> 1)
s_div_x -> s_div_x_shift_1;
"1b" -> s_div_x_shift_1;
{ rank=same; C5; s_div_x_shift_1}
// (x >> 1) + ((s/x) >> 1);
x_shift_1 -> new_x;
s_div_x_shift_1 -> new_x;
{ rank=same; C6; new_x;}
// (old_x <= X)
x -> old_x_lte_new_x;
new_x -> old_x_lte_new_x;
new_x -> x [style=dotted,label="if(¹)"];
{ rank=same; C7; old_x_lte_new_x;}
// if (old_x <= X)
old_x_lte_new_x -> inc_i [style=dotted,arrowhead=normal,label="True"];
// else
"1c" -> inc_i;
i -> inc_i:ne;
inc_i:s -> i:s;
new_x -> mem_i2 [label="if(¹)", style=dotted];
{ rank=same; C8; inc_i; mem_i2};
}
}
}
// Listing
// void heron_sqrt(u32 *mem) {
// int i;
// for (i = 1; i <= mem[0]; i++){
// u32 s = mem[i];
// if (s > 1) {
// // x_0 = (s + 1) / 2
// // without increment to avoid overflow for 0xffffffff
// u32 x = s >> 1;
// u32 old_x = x;
//
// while(1) {
// // x_{n + 1} = (x_n + (s / x_n)) / 2
// x = (x >> 1) + ((s/x) >> 1);
// if (old_x <= x) {
// mem[i] = x;
// break;
// }
// old_x = x;
// }
// mem[i] = x;
// }
// }
//}

48
sqrt.c
View File

@ -10,64 +10,37 @@ void heron_sqrt(u32 *mem) {
int i; int i;
for (i = 1; i <= mem[0]; i++){ for (i = 1; i <= mem[0]; i++){
u32 s = mem[i]; u32 s = mem[i];
if (s > 1) {
// x_0 = (s + 1) / 2 // x_0 = (s + 1) / 2
// without increment to avoid overflow for 0xffffffff // without increment to avoid overflow for 0xffffffff
u32 x = s >> 1; u32 x = s >> 1;
u32 old_x = x; u32 old_x = x;
if (x != 0) {
while(1) { while(1) {
// x_{n + 1} = (x_n + (s / x_n)) / 2 // x_{n + 1} = (x_n + (s / x_n)) / 2
x = (x >> 1) + ((s/x) >> 1); x = (x >> 1) + ((s/x) >> 1);
printf("%d\n", x);
if (old_x <= x) { if (old_x <= x) {
mem[i] = x; mem[i] = x;
break; break;
} }
old_x = x; old_x = x;
} }
}
mem[i] = x; mem[i] = x;
} }
} }
}
//void heron_sqrt2(u32 *mem) {
// int i = 1;
// while(i <= mem[0]) {
// u32 s = mem[i];
// // x_0 = (s + 1) / 2
// // without increment to avoid overflow for 0xffffffff
// u32 x = s >> 1;
// u32 old_x = x;
//
// if (x != 0) {
// while(1) {
// // x_{n + 1} = (x_n + (s / x_n)) / 2
// //x = (x >> 1) + ((s/x) >> 1);
// x = (x / 2) + ((s/x) / 2);
// printf("%d\n", x);
// if (old_x == x) {
// mem[i] = x;
// break;
// }
// old_x = x;
// }
// }
// mem[i] = x;
// i++;
// }
//}
int main() { int main() {
u32 data[] = {0, u32 data[] = {0,
1, 1,
2, 2,
4, 4,
1<<2, 3<<2,
1<<3, 1<<3,
1<<4, 1<<4,
1<<5, 1<<5,
1<<6, 1<<6,
5<<2,
1<<7, 1<<7,
1<<8, 1<<8,
1<<16, 1<<16,
@ -79,23 +52,20 @@ int main() {
1<<30, 1<<30,
0xffffffff}; 0xffffffff};
const int length = sizeof(data)/sizeof(u32); const int length = sizeof(data)/sizeof(u32);
const int mem_size = sizeof(data) + sizeof(u32);
u32* mem = malloc(mem_size); u32* mem = malloc(sizeof(data) + sizeof(u32));
memcpy(mem, data, mem_size); memcpy(&mem[1], data, sizeof(data));
u32* mem2 = malloc(mem_size);
memcpy(mem2, data, mem_size);
mem[0] = length; mem[0] = length;
heron_sqrt(mem); heron_sqrt(mem);
//heron_sqrt2(mem2);
int i = 0; int i = 0;
for (i = 0; i < length; i++) { for (i = 0; i < length; i++) {
printf("s = %u\n", data[i]); printf("s = %u\n", data[i]);
printf("sqrt(s) = %f\n", sqrt(data[i])); printf("sqrt(s) = %f\n", sqrt(data[i]));
printf("heron_sqrt(s) = %d\n", mem[i]); printf("heron_sqrt(s) = %d\n", mem[i+1]);
//printf("heron_sqrt2(s) = %d\n", mem2[i]); puts("\n");
} }
return 0; return 0;
} }