提问人: 提问时间:5/31/2014 最后编辑:zastrowm 更新时间:7/1/2016 访问量:3181
不同的数学 CPU 会生成相同的浮点结果吗?
Will different math CPUs yield the same floating point results?
问:
我正在开发操作系统便携式软件,该软件具有必须在 Linux、UNIX 和 Windows 上运行的单元测试。
想象一下这个单元测试,它断言 IEEE 单精度浮点值 1.26743237e+015f 被转换为字符串:
void DataTypeConvertion_Test::TestToFloatWide()
{
CDataTypeConversion<wchar_t> dataTypeConvertion;
float val = 1.26743237e+015f;
wchar_t *valStr = (wchar_t*)dataTypeConvertion.ToFloat(val);
std::wcout << valStr << std::endl;
int result = wcscmp(L"1.26743E+015", valStr);
CPPUNIT_ASSERT_EQUAL(0, result);
delete [] valStr;
}
我的问题是:只要浮点数是 IEEE,所有操作系统和处理器都会将浮点数转换为字符串“1.26743E+015”吗?我之所以这么问,是因为我知道数学 CPU 可能无法返回准确的结果,我想知道这是否会在不同的处理器上产生不同的结果,因为它们可能在处理器架构内部具有不同的 IEEE 浮点运算硬件实现。
答:
6赞
david.pfx
5/31/2014
#1
可悲的是,答案很可能是否定的。不能保证浮点数与任意字符串之间的转换是跨平台的。
至少原则上,您可能遇到的所有处理器都符合 IEEE 754 标准。该标准相当严格,因为它定义了浮点运算。您可以对浮点数进行加/减/倍增或除法,并合理期望在位级别跨平台获得相同的结果。
该标准还定义了与“字符表示”之间的转换。原则上,这需要符合要求的实现是兼容的,但它有“回旋余地”。并非所有数字都必须产生相同的结果。
您还应该知道,默认精度和格式可能因平台而异。
综上所述,只要 (a) 控制字符串的宽度和精度,而不是将其保留为默认值,您就可以获得所需的结果 (b) 您选择的精度完全在特定格式的最大可用范围内 (c) 避免 NaN 和类似格式。
这里的文章很有帮助。
评论
0赞
supercat
11/17/2014
将字符串转换为 的 .NET 方法并非在所有情况下都执行正确的舍入;对于某些输入字符串,当使用 x87 浮点数学时,它们将在 32 位模式下正确舍入,但在使用 SSE 浮点数学的 64 位模式下则不会。所有平台都应该精确地转换每个字符串,这些字符串距离精确可表示值的 1/4ulp 以内,但当给定一个与最接近的可表示值接近 1/2ulp 的字符串时,可能会有所不同(没有任何东西与最接近的可表示值超过 1/2ulp,因为其他一些可表示值会更接近它)double
评论
std::numeric_limits::epsilon<float>()
获得。对于不同的机器架构/FPU,它可能有所不同。float