编译器以不同的方式处理数学?
compilers processing maths differently?
我做了一个代码来查找给定点的函数的导数。代码读取
#include"stdafx.h"
#include<iostream>
using namespace std;
double function(double x) {
return (3 * x * x);
}
int main() {
double x, y, dy, dx;
cin >> x;
y = function(x);
dx = 0.00000001;
dy = function(x + dx) - y;
cout << "Derivative of function at x = " << x << " is " << (double)dy / dx;
cin >> x;
}
现在我的大学使用turbo C++作为IDE和编译器,而在家里我有Visual Studio(因为TC ++在900p屏幕上看起来很糟糕,但开玩笑)。当我在大学PC上尝试类似的程序时,结果非常混乱,并且比我在家里得到的要准确得多。例如:
例子:
x = 3
@College结果 = 18.something
@Home结果 = 18(精确无小数点)
x = 1
@College结果 = 6.000.....某物
@Home结果 = 6(精确无小数点)
非常大的问题:
为什么不同的编译器给出不同的结果?
我 90% 确定两种情况下的结果是相同的,您看到差异的唯一原因是不同的输出格式。 对于 64 位 IEEE 双精度数学,这些计算的精确结果可能分别为 17.9999997129698385833762586116790771484375 和 6.0000000079440951594733633100986480712890625。
如果要验证该假设,可以通过以下方式打印双精度值:
void printDoubleAsHex( double val )
{
const uint64_t* p = (const uint64_t*)( &val );
printf( "%" PRIx64 "n", *p );
}
并验证两个编译器中的输出相同。
但是,您的两个编译器确实以不同的方式编译您的代码的可能性也有 10%。这种情况并不少见,它甚至可能发生在相同的编译器上,但不同的设置/标志/选项。
最可能的原因是不同的指令集。默认情况下,许多现代编译器会为像您这样的代码生成 SSE 指令,较旧的编译器会生成遗留的 x87 代码(x87 在堆栈上的 80 位浮点值上运行,在这些向量寄存器上的 32 位或 64 位 FP 值上运行 SSE,因此精度存在差异)。另一个原因是舍入模式不同。另一个是特定于编译器的优化,例如Visual C++中的/fp。
- 我可以使用哪种数据结构来处理这种方式
- 如何编写具有相同名称的相同函数,该函数在C++中几乎以相似的方式处理不同的类参数?
- clang++ 是否以更轻松的方式处理系统标头?
- 如何以这种方式处理字符串数组
- 处理无法按预期方式创建的对象,c++
- 跨平台套接字发送,Linux 上的缓冲区常量无效* Windows上的常量字符*,最佳处理方式
- 识别指针处理方式中的错误
- 为什么在指针和数组的情况下,字符数组的处理方式不同
- 为什么这些函数签名的处理方式不同?
- G++ 和 boost 中 regex_replace() 替换字符串中''的不同处理方式
- 常量标识符在C++中有不同的处理方式吗
- 在 C++ 中,get() 和 getline() 对换行符的处理方式不同
- 为什么Visual Studio在调试时对ANSI Escape代码有不同的处理方式
- 在处理回调函数时,通常的异常处理方式是什么?
- 为什么未初始化的const成员在C和c++中的处理方式不同?
- 定义和处理方式不同
- 你能把一个异常继承层次结构包装到另一个吗?——或者,另一种干净的处理方式
- GCC 3.42和VC2008对std::transform的处理方式不同,接受函子的引用或副本
- NaN在不同g++版本中的处理方式不同
- OMP 目标中全局数组(malloc 与静态)的不同处理方式