Windows vs Linux - 数学结果差异 [英] Windows vs Linux - math result difference

查看:38
本文介绍了Windows vs Linux - 数学结果差异的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有 C++ 程序.如果我运行相同部分的代码,Linux 和 Windows 会给出不同的结果.

I have program in C++. If I run same part of code, Linux and Windows are giving different results.

#include <cmath>
#include <cfloat>
#include <cstdio>



#define MPI 3.141592653589793238462
#define DEG_TO_RAD(x) ((x) * 0.0174532925)
#define cot(x)  (1.0 / tan(x))
#define sec(x)  (1.0 / cos(x))

double p1 = DEG_TO_RAD(35);
double p2 = DEG_TO_RAD(65);

double lambertN = log(cos(p1) * sec(p2));
lambertN /= (log(tan(0.25 * MPI + 0.5 * p2) * cot(0.25 * MPI + 0.5 * p1)));


double t = tan(0.25 * MPI + 0.5 * p1);
double lambertF = cos(p1) * pow(t, lambertN);

//---------------------------

//specify input coordinates in degrees
double lon = 160.25;
double lat = 245.75;

double longitude = DEG_TO_RAD(lon - 10);
double latitude  = DEG_TO_RAD(lat);

double c = cot(0.25 * MPI + 0.5 * latitude);
double lambertPhi = lambertF * pow(c, lambertN);

printf("%f", lambertPhi); // here I got different results on Win and Linux

在 Windows 上,我得到了正确的结果(或者看起来是这样,因为最终结果还可以).在 Linux 上,我得到了 NaN 或一些与 Windows 相关的非常小的数字.

On Windows, I got correct result (or it seems so, because final result is OK). On Linux, I got NaN or some very small numbers in comaprison to Windows.

我错过了什么?

编辑 #1:

Windows - Visual Studio 2010 - 通过 GUI 构建

Windows - Visual Studio 2010 - build via GUI

Linux - gcc 版本 4.4.7 20120313 (Red Hat 4.4.7-4) (GCC) - 使用 makefile 构建,标志:CFLAGS = -lm -lstdc++ -Wall -O2

Linux - gcc version 4.4.7 20120313 (Red Hat 4.4.7-4) (GCC) - built with makefile, flags: CFLAGS = -lm -lstdc++ -Wall -O2

两个系统都是 64 位

Both systems are 64bit

附注:如果有人感兴趣,这是 Lambert-Conic 投影方程的一部分.

PS: If anyone is interested, this is part of Lambert-Conic projection equation.

推荐答案

首先,没有真正的理由期待相同的结果,除非您采取积极措施以确保取得特定结果.这C++ 语言定义允许使用中间结果扩展精度.通常,如果编译器执行此操作(并且在英特尔架构上这样做非常频繁),扩展精度将被截断为标准双精度编译器存储到内存时的精度.而当它存储到内存将取决于编译器的内部结构(甚至可能是优化程度).

First, there is no real reason to expect the same results, unless you take active steps to ensure specific results. The C++ language definition allows intermediate results to use extended precision. Typically, if a compiler does this (and doing it is very frequent on an Intel architectures), The extended precision will be truncated to standard double precision when the compiler stores to memory. And when it stores to memory will depend on the internals of the compiler (and probably even on the degree of optimization).

就英特尔而言,现代芯片包含几个浮动点处理器:较旧的 FPU 使用扩展精度,其中因为较新的 SSE 变体没有.但是较新的 SSE 变体在较旧的处理器上不可用.默认情况下,g++(Linux 编译器)使用旧的 FPU,可以在任何地方工作,但是据我所知,Visual C++ 使用 SSE.这意味着通过默认,你会得到不同的结果.两个编译器都有改变这一点的广泛选项,但如果你正在运行默认配置,我希望 g++ 和 Visual给出相同的结果.

In the case of Intel, modern chips contain several floating point processors: the older FPU uses extended precision, where as the newer SSE variants don't. But the newer SSE variants aren't available on older processors. By default, g++ (the Linux compiler) uses the older FPU, to work everywhere, but Visual C++, as far as I can tell, uses SSE. This means that by default, you will get different results. Both compilers have extensive options for changing this, but if you're running the default configuration, I would not expect g++ and Visual to give the same results.

这篇关于Windows vs Linux - 数学结果差异的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆