求高手!!windows与linux的浮点数的问题

软件和网站开发以及相关技术探讨
回复
wgj
帖子: 294
注册时间: 2007-06-02 20:00

求高手!!windows与linux的浮点数的问题

#1

帖子 wgj » 2013-03-14 16:35

同样的一个程序,纯数学计算的,没有什么api,在windows和linux都使用g++编译,为什么结果不一样??
wgj
帖子: 294
注册时间: 2007-06-02 20:00

Re: 求高手!!windows与linux的浮点数的问题

#2

帖子 wgj » 2013-03-14 16:36

上程序

代码: 全选

#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;
}
wgj
帖子: 294
注册时间: 2007-06-02 20:00

Re: 求高手!!windows与linux的浮点数的问题

#3

帖子 wgj » 2013-03-14 16:37

输入38133 49787 9840
linux输出是3295/4302
windows输出却是6590/8604
头像
Kandu
帖子: 108
注册时间: 2008-12-24 12:02
联系:

Re: 求高手!!windows与linux的浮点数的问题

#4

帖子 Kandu » 2013-03-15 11:19

這應該不是 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 開發者居然是接受的,我也不知道他們是怎麼想的。
這類問題,最好還是用分數庫來計算吧,浮點數,不管如何,都存在精度問題的。
wgj
帖子: 294
注册时间: 2007-06-02 20:00

Re: 求高手!!windows与linux的浮点数的问题

#5

帖子 wgj » 2013-03-16 13:18

多谢楼上。看来跨平台真是个令人痛苦的事情。。
回复