![]() |
math/04 のバックアップ(No.2) |
unsigned int isqrt(unsigned int x) { unsigned int a = 0, b = 65535, c; do { c = (a + b) / 2; if (x < c * c) b = c; else a = c; } while (a + 1 < b); return a; }
bits isqrt(bits X) /* Xはとりあえず、 0.xxxxxxxx みたいな数値。Xにはxxxxxxxの部分が入る。 */ /* sqrt(3)を計算したい場合は、X=.110000000000...(2進数) として、結果を2倍すればよい。 2進数の0.11は10進数の0.75のことであり、sqrt(3/4)に相当する。これは sqrt(3)/2だから、 結果を2倍すればいいわけだ。 */ { unsigned int x = 0, y = 0, i; for (i = 0; i < 32; i++) { x = x * 4 + high(X, 2); /* xを4倍してXから上位2bitを持ってくる。 次のhighで続きを持ってこられるようにXも4倍する。 */ y *= 2; if (x >= y * 2 + 1) { x -= y * 2 + 1; y++; } } return (bits) y; /* yの前に0.を補う感じ */ }
unsigned int isqrt(unsigned int xx) { unsigned int x = 0, y = 0, i; for (i = 0; i < 16; i++) { x = x << 2 | (xx >> 30); /* アセンブラならここは SHLD を使えば簡単にできる */ xx <<= 2; y <<= 1; if (x >= y * 2 + 1) { x -= y * 2 + 1; y++; } } return y; }
コメント | お名前 | NameLink | |