user-0 提问: 关于cpu计算出错的问题

回复:
user: user-0
content: 引用 15 楼 DelphiGuy 的回复:这个应该就是你用的power()、qrt()和库函数之间的误差造成的。 你可以使用如下函数直接FPU计算分的sin、cos值来保证精度： double sinm(double x) {   static const double K = 3.1415926535897932 / 10800;    __asm{     fld qword ptr x     fmul qword ptr K     fsin   } }  double cosm(double x) {   static const double K = 3.1415926535897932 / 10800;    __asm{     fld qword ptr x     fmul qword ptr K     fcos   } }我已经解决了这个问题了，代码写错了。

user: user-0
content: double qrt(double x) { double t=0,y=1; int i=0; t=y/2; while(i++<60000) { if(power(t)>x) {	y=t; t=t/2; } else if(power(t)==x) 	return t; else if(power(y)==x) 	return y; else if(power(t)<x) 	t=(t+y)/2; } return (t+y)/2; }

user: user-0
content: 引用 14 楼 qq_30239507 的回复:我觉得是计算开方的代码有问题，你改进一下试试。 我也觉得可能是我的计算开方的代码有问题，但是我只计算1以内的开方啊，是有点一点bug，比如正好等于的时候。改进了一下还是有会出现这样的情况。

user: user-1
content: 这个应该就是你用的power()、qrt()和库函数之间的误差造成的。 你可以使用如下函数直接FPU计算分的sin、cos值来保证精度： double sinm(double x) {   static const double K = 3.1415926535897932 / 10800;    __asm{     fld qword ptr x     fmul qword ptr K     fsin   } }  double cosm(double x) {   static const double K = 3.1415926535897932 / 10800;    __asm{     fld qword ptr x     fmul qword ptr K     fcos   } }

user: user-2
content: 我觉得是计算开方的代码有问题，你改进一下试试。

user: user-0
content: 引用 6 楼 paschen 的回复:首先浮点数是会有误差的，很多十进制小数都没办法用二进制精确表示  其次，double a = cos(5.0*3.14159265358979323846/180.0); 我这得到的是：0.9961946980917455510800分之5π弧度。是要做一个角度制三角函数表，主要是前面四项是完全一样的，为什么第五项就差了那么多

user: user-3
content: 估计更多的还是你的计算有错误

user: user-0
content: 引用 7 楼 DelphiGuy 的回复:引用 4 楼 baidu_32238993 的回复:[quote=引用 1 楼 DelphiGuy 的回复:] cos(5)不应该是0.99...啊单位是分，六十分之一度  这么说是cos(5.0 / 60)，不过如果不是你的参数中间计算步骤引入了误差，那就是你的电脑浮点部件有问题了，也许浮电优化的问题？ 我用一台intel i7、一台AMD A10电脑验证了一下：cos(5.0 / 60) = 0.996529786700559 可以用FPU cos指令验证，这个精度最高： double cos_asm(double x) {   __asm{     fld qword ptr x     fcos   } } [/quote]不是弧度..是角度，角分秒制

user: user-3
content: FPU内部是80Bits浮点数 C,C++中，VC 不能使用80Bits 浮点数。

user: user-0
content: 引用 5 楼 fefe82 的回复:你的程序、编译器（版本号）、操作系统（版本号）、CPU型号 ..... 都是啥？ 编译器vs2010，系统win7 64位，cpu i7四代，源代码 #include <stdio.h> #include <float.h> #include <time.h> #include <math.h> double power(double x); double qrt(double x); int main (void) { double t=0,k=0,c=0,ka=0,ca=0,ta=0; int i=1; const double sin=0.000290888204563; int a=0,b=0; a=clock(); t=sin; ta=sin; k=qrt(1-power(sin)); printf("%0.15f ",k); ka=sqrt(1-power(sin)); printf("%0.15f ",ka); c=k; ca=ka; printf("sin%d=%0.9f,cos%d=%0.9f\n",i,t,i,k); while(i++<50) { 	t = t*k+c*sin;     c=qrt(1-power(t)); 	printf("%0.15f",1-power(t)); 	printf("sin%d=%0.9f,cos%d=%0.9f\n",i,t,i,c); 	ta=ta*ka+ca*sin;     ca=sqrt(1-pow(ta,2)); 	printf("sin%d=%0.9f,cos%d=%0.9f\n",i,ta,i,ca); } b=clock(); b=b-a; printf("time=%d",b); getchar(); getchar(); return 0; } double power(double x) { 	double t=0; 	t=x*x; return t; } double qrt(double x) { double t=0,y=1; int i=0; t=y/2; while(i++<60000) { if(power(t)>x)   {	y=t; t=t/2; } else  	t=(t+y)/2; } return (t+y)/2; }

user: user-1
content: 浮点优化

user: user-1
content: 引用 4 楼 baidu_32238993 的回复:引用 1 楼 DelphiGuy 的回复:cos(5)不应该是0.99...啊单位是分，六十分之一度  这么说是cos(5.0 / 60)，不过如果不是你的参数中间计算步骤引入了误差，那就是你的电脑浮点部件有问题了，也许浮电优化的问题？ 我用一台intel i7、一台AMD A10电脑验证了一下：cos(5.0 / 60) = 0.996529786700559 可以用FPU cos指令验证，这个精度最高： double cos_asm(double x) {   __asm{     fld qword ptr x     fcos   } }

user: user-4
content: 首先浮点数是会有误差的，很多十进制小数都没办法用二进制精确表示  其次，double a = cos(5.0*3.14159265358979323846/180.0); 我这得到的是：0.99619469809174555

user: user-5
content: 你的程序、编译器（版本号）、操作系统（版本号）、CPU型号 ..... 都是啥？

user: user-0
content: 引用 1 楼 DelphiGuy 的回复:cos(5)不应该是0.99...啊单位是分，六十分之一度

user: user-0
content: 但是前面好几项都一样啊

user: user-6
content: 首先CPU计算不会出错，只可能无法表示足够精度。 计算结果不同的原因，一是算法不同，比如直接使用泰勒公式计算、还是先将参数平移到某一区间后再用泰勒公式，余项是不一样的，二是计算保留的精度问题，比如泰勒公式中各项的系数保留了多少位小数，float还是double有效数字位数是不一样的

user: user-1
content: cos(5)不应该是0.99...啊