流程圖:
程式碼:
- #include <stdint.h>
- double msqrt(double x)
- {//直式開方,適用 IEEE754 double
- int i;
- uint64_t r=0,k;
- //取得浮點數的s,e,f
- uint32_t s=(*(uint64_t*)&x)>>63;
- int32_t e=(*(uint64_t*)&x)>>52&0x7FF;
- uint64_t f=(*(uint64_t*)&x)&0xFFFFFFFFFFFFFllu;
- e-=1023;
- if(e==1024)
- return x;
- if(e==-1023)
- {
- if(f==0)
- return 0.0;
- else
- {
- //正規化
- while(!(f&0x10000000000000llu))
- {
- f<<=1;
- --e;
- }
- }
- }
- if(s==1)
- {
- k=0xFFFFFFFFFFFFFFFF;
- return *(double*)&k; //return NaN;
- }
- //位值調整,並把e開根號
- f=(e&1)?(f|0x10000000000000llu)<<1:(f|0x10000000000000llu);
- e=(e>>1)|(e&0x80000000);
- //對f開根號
- for(i=52;i>=0;i-=2)
- {
- k=(r<<2|1)<<i;
- if(f>=k)
- {
- f-=k;
- r=r<<1|1;
- }
- else
- r<<=1;
- }
- for(i=0;i<26;++i)
- {
- f<<=2;
- k=r<<2|1;
- if(f>=k)
- {
- f-=k;
- r=r<<1|1;
- }
- else
- r<<=1;
- }
- //四捨五入
- if( (f<<2) >= (r<<2|1) )
- ++r;
- //e,f合併為double回傳
- k=e+1023;
- k=(r&0xFFFFFFFFFFFFFllu)|k<<52;
- return *(double*)&k;
- }
文章標籤
全站熱搜
