From 1d6367161d021c4c3c8dd8611f31d9e194bcb053 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rg=20Thalheim?= Date: Fri, 6 Dec 2013 15:11:41 +0100 Subject: [PATCH] . --- graph.dot | 131 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ sqrt.c | 60 +++++++------------------ 2 files changed, 146 insertions(+), 45 deletions(-) create mode 100644 graph.dot diff --git a/graph.dot b/graph.dot new file mode 100644 index 0000000..907749e --- /dev/null +++ b/graph.dot @@ -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; +// } +// } +//} + diff --git a/sqrt.c b/sqrt.c index e1f9278..027f647 100644 --- a/sqrt.c +++ b/sqrt.c @@ -10,64 +10,37 @@ void heron_sqrt(u32 *mem) { int i; for (i = 1; i <= mem[0]; i++){ 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 (s > 1) { + // 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); - printf("%d\n", x); if (old_x <= x) { mem[i] = x; break; } 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() { u32 data[] = {0, 1, 2, 4, - 1<<2, + 3<<2, 1<<3, 1<<4, 1<<5, 1<<6, + 5<<2, 1<<7, 1<<8, 1<<16, @@ -79,23 +52,20 @@ int main() { 1<<30, 0xffffffff}; const int length = sizeof(data)/sizeof(u32); - const int mem_size = sizeof(data) + sizeof(u32); - u32* mem = malloc(mem_size); - memcpy(mem, data, mem_size); - u32* mem2 = malloc(mem_size); - memcpy(mem2, data, mem_size); + + u32* mem = malloc(sizeof(data) + sizeof(u32)); + memcpy(&mem[1], data, sizeof(data)); mem[0] = length; heron_sqrt(mem); - //heron_sqrt2(mem2); int i = 0; 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("heron_sqrt(s) = %d\n", mem[i]); - //printf("heron_sqrt2(s) = %d\n", mem2[i]); + printf("sqrt(s) = %f\n", sqrt(data[i])); + printf("heron_sqrt(s) = %d\n", mem[i+1]); + puts("\n"); } return 0; }