下面给出实现这个功能的代码和测试代码。
顺便说一下,在2楼长提到的各个算法的选择都是在实验的基础上得出的,既能保证正确性,又是的速度不致太慢。- #include <math.h>
-
- typedef unsigned long DWORD;
- typedef unsigned char BYTE;
-
- inline DWORD log2(DWORD n)
- {
- _asm
- {
- mov ecx,n
- bsr eax,ecx
- }
- }
-
- extern "C" unsigned char sqrtTab[]=
- {
- 0, 1, 1, 1, 2, 2, 2, 2,
- 2, 3, 3, 3, 3, 3, 3, 3,
- 4, 4, 4, 4, 4, 4, 4, 4,
- 4, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 6, 6, 6, 6,
- 6, 6, 6, 6, 6, 6, 6, 6,
- 6, 7, 7, 7, 7, 7, 7, 7,
- 7, 7, 7, 7, 7, 7, 7, 7,
- 128,128,129,130,131,132,133,134,
- 135,136,137,138,139,140,141,142,
- 143,144,144,145,146,147,148,149,
- 150,150,151,152,153,154,155,155,
- 156,157,158,159,160,160,161,162,
- 163,163,164,165,166,167,167,168,
- 169,170,170,171,172,173,173,174,
- 175,176,176,177,178,178,179,180,
- 181,181,182,183,183,184,185,185,
- 186,187,187,188,189,189,190,191,
- 192,192,193,193,194,195,195,196,
- 197,197,198,199,199,200,201,201,
- 202,203,203,204,204,205,206,206,
- 207,208,208,209,209,210,211,211,
- 212,212,213,214,214,215,215,216,
- 217,217,218,218,219,219,220,221,
- 221,222,222,223,224,224,225,225,
- 226,226,227,227,228,229,229,230,
- 230,231,231,232,232,233,234,234,
- 235,235,236,236,237,237,238,238,
- 239,240,240,241,241,242,242,243,
- 243,244,244,245,245,246,246,247,
- 247,248,248,249,249,250,250,251,
- 251,252,252,253,253,254,254,255
- };
-
- extern "C"
- DWORD __fastcall UintSqrt(DWORD n)
- {
- DWORD bc;
- DWORD r;
- DWORD r1;
-
- if (n<64)
- return sqrtTab[n];
-
- bc=log2(n)/2;
- switch (bc)
- {
- case 3:
- r=(sqrtTab[n]>>4);
- r1=r+1;
- if (r1*r1<=n)
- r++;
- break;
- case 4:
- r=(sqrtTab[n>>2]>>3);
- r1=r+1;
- if (r1*r1<=n)
- r++;
- break;
-
- case 5:
- r=(sqrtTab[n>>4]>>2);
- r1=r+1;
- if (r1*r1<=n)
- r++;
- break;
-
- case 6:
- r=(sqrtTab[n>>6]>>1);
- r1=r+1;
- if (r1*r1<=n)
- r++;
-
- break;
-
- case 7:
- r=(sqrtTab[n>>8]);
- r1=r+1;
- if (r1*r1<=n)
- r++;
- break;
-
- case 8:
- r=(sqrtTab[n>>10]<<1);
- r= (n/r + r)/2;
- if (r*r>n) r--;
- break;
-
- case 9:
- r=(sqrtTab[n>>12]<<2);
- r= (n/r + r)/2;
- if (r*r>n) r--;
- break;
-
- case 10:
- r=(sqrtTab[n>>14]<<3);
- r= (n/r + r)/2;
- if (r*r>n) r--;
- break;
-
- case 11:
- r=(sqrtTab[n>>16]<<4);
- r= (n/r + r)/2;
- if (r*r>n) r--;
- break;
-
- case 12:
- r=(sqrtTab[n>>18]<<5);
- r= (n/r + r)/2;
- if (r*r>n) r--;
- break;
-
- case 13:
- r=(sqrtTab[n>>20]<<6);
- r= (n/r + r)/2;
- if (r*r>n) r--;
- break;
-
- case 14:
- r=(sqrtTab[n>>22]<<7);
- r= (n/r + r)/2; //2次牛顿迭代
- r= (n/r + r)/2;
- if (r*r>n) r--;//调整
- break;
-
- case 15:
- r=(sqrtTab[n>>24]<<8);
- r= (n/r + r)/2; //2次牛顿迭代
- r= (n/r + r)/2;
- if (r*r>n) r--;//调整
- break;
- }
- return r;
- }
-
复制代码
[ 本帖最后由 liangbch 于 2009-2-13 10:45 编辑 ] |