|
math/04 のバックアップ(No.3) |
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 | |