为什么我在每个 std::nexttowards 函数调用上都得到相同的结果

Why am I getting the same results on every std::nexttoward function call

本文关键字:结果 函数调用 nexttowards std 为什么      更新时间:2023-10-16

为什么下面的代码在每次std::nexttoward函数调用时都返回相同的数字?

#include <cmath>
#include <iostream>
#include <limits>
int main()
{
std::cout.precision(std::numeric_limits<double>::max_digits10);
std::cout.setf(std::ios::fixed);
auto foo = 0.00000000000011134;
std::cout << foo << std::endl;
for (int i = 0; i < 100; ++i)
{
foo = std::nexttoward(foo, 1.0);
std::cout << foo << std::endl;
}
}

http://coliru.stacked-crooked.com/a/551b6e2b867b2f3b

这里提到的任何标志都没有设置(FE_OVERFLOW, FE_UNDERFLOW и FE_INEXACT) 。

这是因为浮点格式通常面向保留一定数量的有效数字。

std::cout.setf(std::ios::fixed);

使用具有较小数值的std::ios::fixed格式会强制格式化输出插入一堆不重要的"前导"零(在小数点之后)。这就是您在测试程序输出中真正看到的内容。这是以截断实际有效数字为代价的,当I/O库必须在固定precision()之后切断所有内容时。

删除std::ios::fixed格式标志(并保持precision())后,输出变为您所期望的(使用 gcc 7.2.1 测试了自己,并在 Colliru 上重现):

1.1134e-13
1.1134000000000001e-13
1.1134000000000002e-13
1.1134000000000003e-13
1.1134000000000005e-13
1.1134000000000006e-13
1.1134000000000007e-13
1.1134000000000008e-13
1.113400000000001e-13
1.1134000000000011e-13
1.1134000000000012e-13

。等

将小数点向左移动十三位(这就是e-13所说的),然后亲自看看在std::ios::fixed砍掉指定位数后的所有内容后会发生什么。