求高手!!windows与linux的浮点数的问题
-
- 帖子: 294
- 注册时间: 2007-06-02 20:00
求高手!!windows与linux的浮点数的问题
同样的一个程序,纯数学计算的,没有什么api,在windows和linux都使用g++编译,为什么结果不一样??
-
- 帖子: 294
- 注册时间: 2007-06-02 20:00
Re: 求高手!!windows与linux的浮点数的问题
上程序
代码: 全选
#include<cstdio>
#include<cstring>
#include<cmath>
#include<iostream>
#include<vector>
#include<queue>
#include<algorithm>
#define pf(i,s,t) for (int (i)=s;(i)<(t);(i)++)
#define mf(i,s,t) for (int (i)=s;(i)<(t);(i)--)
#define mt(a,d) memset((a),(d),sizeof(a))
using namespace std;
main()
{
long long x,y,n;
cin>>x>>y>>n;
double k=x/(y*1.0);
double min=100;
long long a,b;
int minb=1000000;
for (long long i=1;i<=n;i++)
{
long long z=(long long)floor(i*k);
if (min>fabs((i*x-y*z)*1.0/(y*i)))
{
min=fabs((i*x-y*z)*1.0/(y*i));
a=z;
b=i;
}
z++;
if (min>fabs((i*x-y*z)*1.0/(y*i)))
{
min=fabs((i*x-y*z)*1.0/(y*i));
a=z;
b=i;
}
}
cout<<a<<'/'<<b<<endl;
return 0;
}
-
- 帖子: 294
- 注册时间: 2007-06-02 20:00
Re: 求高手!!windows与linux的浮点数的问题
输入38133 49787 9840
linux输出是3295/4302
windows输出却是6590/8604
linux输出是3295/4302
windows输出却是6590/8604
- Kandu
- 帖子: 108
- 注册时间: 2008-12-24 12:02
- 联系:
Re: 求高手!!windows与linux的浮点数的问题
這應該不是 OS 的原因。應該是你用的 ia32 版的 windows 和 x86-64 版的 linux, 所以 g++ 的 target 不同了。所以產生的 asm instruction 也不同,不同指令的精度產生了這個問題。
第一次迴圈過後兩者沒什麼不同。但第二次迴圈時。 z++ 後,照理 if 條件是爲真的。但只在 i386 下爲真, x86-64 機器上就不會真。主要就是 asm instruction 的精度原因。
在爲 ia32 產生組合碼時,用的是 fpu 來進行浮點計算和比較。而 Linux(Windows 應該也是如此) 不管在 ia32/x86-64 都是設 fpu 的精度爲擴展精度(fpu 有單精度,雙精度,擴展精度可調),也就是 80bit 的精度來計算的。你用的 double, 64bit 會自動被 fpu 轉換爲 80bit 的浮點數來進行存儲,計算,存放結果。
x86-64 保證有 sse 指令擴展可用。 gcc 生成的 asm 就用那些指令來計算。但存儲,計算,結果的精度只有 32/64bit(ss/sd 後綴)。所以在 x86-64 上, gcc 生成的浮點計算代碼的精度反而比 ia32 下小了。因爲精度原因,原本 min > ... ,結果 min = ... 不成立。
這樣巨大的精度丟失(80-64=16bit),gcc 開發者居然是接受的,我也不知道他們是怎麼想的。
這類問題,最好還是用分數庫來計算吧,浮點數,不管如何,都存在精度問題的。
第一次迴圈過後兩者沒什麼不同。但第二次迴圈時。 z++ 後,照理 if 條件是爲真的。但只在 i386 下爲真, x86-64 機器上就不會真。主要就是 asm instruction 的精度原因。
在爲 ia32 產生組合碼時,用的是 fpu 來進行浮點計算和比較。而 Linux(Windows 應該也是如此) 不管在 ia32/x86-64 都是設 fpu 的精度爲擴展精度(fpu 有單精度,雙精度,擴展精度可調),也就是 80bit 的精度來計算的。你用的 double, 64bit 會自動被 fpu 轉換爲 80bit 的浮點數來進行存儲,計算,存放結果。
x86-64 保證有 sse 指令擴展可用。 gcc 生成的 asm 就用那些指令來計算。但存儲,計算,結果的精度只有 32/64bit(ss/sd 後綴)。所以在 x86-64 上, gcc 生成的浮點計算代碼的精度反而比 ia32 下小了。因爲精度原因,原本 min > ... ,結果 min = ... 不成立。
這樣巨大的精度丟失(80-64=16bit),gcc 開發者居然是接受的,我也不知道他們是怎麼想的。
這類問題,最好還是用分數庫來計算吧,浮點數,不管如何,都存在精度問題的。
-
- 帖子: 294
- 注册时间: 2007-06-02 20:00
Re: 求高手!!windows与linux的浮点数的问题
多谢楼上。看来跨平台真是个令人痛苦的事情。。