我在使用MSVC和GCC的std :: abs时得到的结果不正确
#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;
}
Run Code Online (Sandbox Code Playgroud)
上面的代码在VC++(带有更新的MSVS 2015 CE)和gcc 4.9.2上产生了不同的结果
使用MSVC
288.062
288.063
Run Code Online (Sandbox Code Playgroud)
与GCC
288.062
288.062
Run Code Online (Sandbox Code Playgroud)
现在实际结果是288.062,这对于gcc与std :: abs和std :: sqrt是正确的.但是当使用std :: sqrt和std :: abs时,msvc有不同的结果,这可能是msvc2015中的一个错误.
但是看看xcomplex的代码,我不明白_Fabs()的实现.有人可以帮助我理解这个特定的代码,并可能分析代码如何以这样的错误结束.
"现在实际结果是288.062 [...]." - 实际结果是288.06249...,或类似的东西,不能用a float或a表示double.
两个编译器实际上都返回相同的值,您可以通过打印更多数字来检查:
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';
Run Code Online (Sandbox Code Playgroud)
输出(VC 19.0和GCC 4.9.3):
sqrt:
288.062
288.062493219787313591950805858
abs:
288.062
288.0625
Run Code Online (Sandbox Code Playgroud)
这两种编译器实际上返回288.0625为std::abs1,但GCC输出288.62(楼)和VC 288.063(小区) -这是不是一个"问题" std::abs,但在输出方式的"问题"被格式化2.
1个这两种编译器返回一个不太近似值std::abs,因为你正在使用float的std::abs,而你正在使用double与std::sqrt.更换6.并288.通过6.f和288.f或std::complex<float>通过std::complex<double>,你会得到相同的结果与std::sqrt和std::abs.
2据我所知,标准没有定义一种在使用时舍入浮点值的方法std::ostream,实际的规格来自printf格式转换%f,它只推荐一种舍入方式(我认为,这是gcc使用圆形的方式)一半甚至").
| 归档时间: |
|
| 查看次数: |
88 次 |
| 最近记录: |