開根號幾種寫法
阿新 • • 發佈:2019-01-04
#include <stdio.h> #include <stdlib.h> #include <math.h> #include <time.h> #include <xmmintrin.h> #include "util.h" #define eps 0.00001 float SqrtByBisection(float n) { if(n<0) { return -1.0; } else { float low,up,mid,last; low=0,up=(n<1?1:n); mid=(low+up)/2; do { if(mid*mid>n) up=mid; else low=mid; last=mid; mid=(up+low)/2; //printf("mid is %f,last is %f\n",mid,last); }while(fabsf(mid-last) > eps); return mid; } } float SqrtByNewton(float x) { //int temp = (((*(int *)&x)&0xff7fffff)>>1)+(64<<23); int temp=0x1fc00000+((*(int *)&x)>>1); //int temp=0x1fbd1e2d+((*(int *)&x)>>1); float val=*(float*)&temp; //float val=x; val =(val + x/val) / 2; val =(val + x/val) / 2; val =(val + x/val) / 2; return val; } float SqrtByCarmack( float number ) { int i; float x2, y,last; const float threehalfs = 1.5F; x2 = number * 0.5F; y = number; i = * ( int * ) &y; // evil floating point bit level hacking i = 0x5f375a86 - ( i >> 1 ); // what the fuck? y = * ( float * ) &i; printf("init is %f\n",y); y = y * ( threehalfs - ( x2 * y * y ) ); // 1st iteration y = y * ( threehalfs - ( x2 * y * y ) ); // 2nd iteration, this can be removed y = y * ( threehalfs - ( x2 * y * y ) ); // 2nd iteration, this can be removed return number*y; } float SqrtByRSQRTSS(float a) { float b=a; __m128 in = _mm_load_ss(&b); __m128 out = _mm_rsqrt_ss(in); _mm_store_ss(&b, out); return a*b; } float SqrtBySQRTSS(float a) { __m128 in = _mm_load_ss(&a); __m128 out = _mm_sqrt_ss(in); _mm_store_ss(&a, out); return a; } int main() { clock_t start,end; struct timeval start1,finish1; float s; int i; FILE* fp; gettimeofday(&start1,NULL); for(i=1;i<3000001;i++) { s=SqrtByBisection(i); } gettimeofday(&finish1,NULL); printf("bisection value:%f,run time of bisection is %f\n",s,difftime_ms(finish1,start1));// gettimeofday(&start1,NULL); for(i=1;i<3000001;i++) { s=SqrtByNewton(i); } gettimeofday(&finish1,NULL); printf("newton value:%f,run time of newton is %f\n",s,difftime_ms(finish1,start1));// gettimeofday(&start1,NULL); //for(i=1;i<3000001;i++) { s=SqrtByCarmack(3000001); } gettimeofday(&finish1,NULL); printf("carmack value:%f,run time of carmack is %f\n",s,difftime_ms(finish1,start1)); gettimeofday(&start1,NULL); for(i=1;i<3000001;i++) { s=sqrtf(i); } gettimeofday(&finish1,NULL); printf("system value:%f,run time of system is %f\n",s,difftime_ms(finish1,start1)); gettimeofday(&start1,NULL); for(i=1;i<3000001;i++) { s=SqrtByRSQRTSS(i); } gettimeofday(&finish1,NULL); printf("RSQRTSS value:%f,run time of RSQRTSS is %f\n",s,difftime_ms(finish1,start1)); gettimeofday(&start1,NULL); for(i=1;i<3000001;i++) { s=SqrtBySQRTSS(i); } gettimeofday(&finish1,NULL); printf("SQRTSS value:%f,run time of SQRTSS is %f\n",s,difftime_ms(finish1,start1)); }