2016-08-16 64 views
-2

我有从标准::绝对不正确的结果与MSVC和GCC为什么标准:: ABS输出不正确上MSVC2015

#include <cmath> 
#include <iostream> 
#include <complex> 

int main() 
{ 
    std::cerr << std::sqrt((-6.)*(-6.) + 288.*288.) << "\n"; 
    std::cerr << std::abs(std::complex<float>(-6, 288)) << std::endl; 

    return 0L; 
} 

以上代码生成VC上不同的结果++(MSVS 2015 CE与更新)和GCC 4.9.2

随着MSVC

288.062 
288.063 

随着GCC

288.062 
288.062 

现在实际结果是288.062,这在gcc上用std :: abs和std :: sqrt是正确的。但是当使用std :: sqrt和std :: abs可能是msvc2015中的一个bug时,msvc会有不同的结果。

但看着xcomplex的代码,我不明白_Fabs()的实现。有人能帮我理解这个特定的代码,并且可以分析代码如何以这样的错误结束。

+1

请注意,在第一行中,您正在使用双打。 –

+0

您是否真的认为所有这些浮点操作都会为两个不同的编译器产生完全相同的结果,因为浮点数是近似值?如果您使用相同的编译器得到不同的结果,但改变了一些编译器选项(如优化或其他设置),我不会感到惊讶。 – PaulMcKenzie

回答

6

“现在实际结果是288.062 [...]”。 - 实际结果是288.06249...,或类似的东西,它不能完全由floatdouble表示。

两种编译器实际上返回相同的值,可以通过印刷更多的数字检查:

double re = -6, im = 288; 
std::cout << "sqrt: " << '\n' 
      << std::setprecision(6) << std::sqrt(re * re + im * im) << '\n' 
      << std::setprecision(30) << std::sqrt(re * re + im * im) << '\n'; 
std::cout << "abs: " << '\n' 
      << std::setprecision(6) << std::abs(std::complex<float>(im, re)) << '\n' 
      << std::setprecision(30) << std::abs(std::complex<float>(im, re)) << '\n'; 

输出(既VC 19.0和GCC 4.9.3):

sqrt: 
288.062 
288.062493219787313591950805858 
abs: 
288.062 
288.0625 

两种编译器实际上返回288.0625std::abs ,但GCC输出288.62(floor)和VC 288.063(ceil) - 这不是std::abs中的“问题”,而是“问题”输出格式为。

这两种编译器,因为使用的是floatstd::abs,而你正在使用doublestd::sqrt返回与std::abs不太近似值。用6.f288.fstd::complex<float>std::complex<double>替代6.288.,您将得到与std::sqrtstd::abs相同的结果。

据我所知,使用std::ostream当标准没有定义舍入浮点值的一种方式,实际规格来自printf格式转换%f建议四舍五入的方式(我认为这是gcc使用“round half to even”的方式)。

+0

^1或更改为'std :: complex (-6,288)' –

相关问题