unsigned long sqrtll(unsigned long long x)
{
uint32_t y,t1,t2;
- uint32_t x0=x, x1=x>>32;
+ uint32_t x0 = x, x1 = x >> 32;
#ifndef __GNUC__
}
}
- while(!(t1&0x80000000)){
- t1<<=1;
+ while (!(t1 & 0x80000000)) {
+ t1 <<= 1;
t2--;
}
#else /*__GNUC__*/
t2 = __builtin_clz(x1);
t1 = (x1 << t2) | ((x0 >> (32 - t2)));
t2 = 63 - t2;
- }else{
+ } else {
if (!x0)
return 0;
t2 = __builtin_clz(x0);
if (!x1) {
y= (y + x0 / y + 1) / 2;
y= (y + x0 / y + 1) / 2;
- } else if (t2<24) {
+ } else if (x1 < 0x00010000) {
uint32_t y0, y1, y2, xt, r;
xt = (x1 << 16) | (x0 >> 16);
return y;
}
+#ifdef __GNUC__
+
+unsigned long sqrtll_approx(unsigned long long x)
+{
+ unsigned int r;
+ uint32_t x1 = x >> 32;
+ if (x1 < 0x00010000)
+ return sqrtll(x);
+
+ r = __builtin_clz(x1);
+ r = (17 - r) / 2;
+ x1 = sqrtll(x >> (r * 2));
+
+ return x1 << r;
+}
+
+#endif /*__GNUC__*/
+
#else
unsigned long sqrtll(unsigned long long x)
#include <system_def.h>
#include <lt_timer.h>
unsigned long sqrtll(unsigned long long x);
+ unsigned long sqrtll_approx(unsigned long long x);
#define main sqrtll_main
#ifdef LPC_TIM0
#define sqrtll_ticks() (LPC_TIM0->TC)
sqr=(unsigned long long int)inp*inp;
cli();
spent=sqrtll_ticks();
- res=sqrtll(sqr);
+ res=sqrtll_approx(sqr);
spent=sqrtll_ticks()-spent;
sti();
printf("sqrtll: inp=%lu, res=%lu, spent=%u\n",inp,res,(int)spent);
}else{
inp=0; incr=1; cnt=0;
+ int eps=1;
lt_mstime_update();
time=actual_msec;
do{
- sqr=(unsigned long long int)inp*inp;
- res=sqrtll(sqr);
- if(0||(inp!=res)){
- printf("sqrt error %lu -> %lu diff %ld sqr 0x%llx\n",inp,res,inp-res,sqr);
- res=sqrtll(sqr);
+ sqr=(unsigned long long int)inp * inp;
+ res=sqrtll_approx(sqr);
+ if(0||(labs(inp-res)) >= eps){
+ printf("\nsqrt error %lu -> %lu diff %ld sqr 0x%llx\n",inp,res,inp-res,sqr);
+ eps<<=1;
+ res=sqrtll_approx(sqr);
}
- inp+=incr; cnt++;
+ cnt++;
+ if(inp>0xffffffff-incr)
+ break;
+ inp+=incr;
if(inp&0xfff) continue;
if(inp&((incr<<19)-1)) continue;
incr<<=1;
printf(".");fflush(NULL);
- }while(inp);
+ }while(1);
lt_mstime_update();
time=actual_msec-time;
printf("\nsqrtll OK, spent %ld cnt %ld\n",time,cnt);