isqrt.c
00001
00002
00003
00004
00005
00006
00007
00008
00009
00010 #include "isqrt.h"
00011
00012
00021 unsigned long isqrt(unsigned long i) {
00022 int sft = 0;
00023 unsigned short y, y0, y1, sum;
00024
00025 if (i < 2) {
00026 return i;
00027 }
00028 while (0 < (signed long)i) {
00029 i <<= 1L;
00030 sft++;
00031 }
00032 y1 = (unsigned short)(i >> 16L);
00033 y0 = (~y1) & 0xffff;
00034 y = (y0 * 0x8000) >> 16;
00035 sum = y;
00036 y = (y * y0) >> 16;
00037 y = (y * 0x4000) >> 16;
00038 sum += y;
00039 y = (y * y0) >> 16;
00040 y = (y * 0x8000) >> 16;
00041 sum += y;
00042 y = (y * y0) >> 16;
00043 y = (y * 40960) >> 16;
00044 sum += y;
00045 y = (y * y0) >> 16;
00046 y = (y * 45875) >> 16;
00047 sum += y;
00048 y = ~sum;
00049 y += ((signed short)((i -(unsigned long)y * (unsigned long)y) >> 16L)) >> 1;
00050 if (sft & 1) {
00051 sft >>= 1;
00052 y = (unsigned short)((0x8000L + (unsigned long)(y >> sft) * 46341L)>> 16L);
00053 }else {
00054 sft >>= 1;
00055 y = y >> sft;
00056 }
00057 return y;
00058 }
00059