这些是在谈论两个略有不同的事情。
7.225 1位是数字可以在内部存储的精度。例如,如果您使用双精度数进行计算(因此您从 15 位精度开始),然后将其四舍五入为单精度数,那么您在该点留下的精度大约为7位数。
6位数字是指通过从十进制数字字符串到浮点数,然后再返回到另一个十进制数字字符串的往返转换可以保持的精度。
所以,假设我从一个像1.23456789
字符串这样的数字开始,然后将其转换为 float32,然后将结果转换回字符串。完成此操作后,我可以期望 6 位数字完全匹配。第七位数字可能是四舍五入的,所以我不一定期望它匹配(尽管它可能是原始字符串的 +/- 1。
例如,考虑以下代码:
#include <iostream>
#include <iomanip>
int main() {
double init = 987.23456789;
for (int i = 0; i < 100; i++) {
float f = init + i / 100.0;
std::cout << std::setprecision(10) << std::setw(20) << f;
}
}
这将生成如下表:
987.2345581 987.2445679 987.2545776 987.2645874
987.2745972 987.2845459 987.2945557 987.3045654
987.3145752 987.324585 987.3345947 987.3445435
987.3545532 987.364563 987.3745728 987.3845825
987.3945923 987.404541 987.4145508 987.4245605
987.4345703 987.4445801 987.4545898 987.4645386
987.4745483 987.4845581 987.4945679 987.5045776
987.5145874 987.5245972 987.5345459 987.5445557
987.5545654 987.5645752 987.574585 987.5845947
987.5945435 987.6045532 987.614563 987.6245728
987.6345825 987.6445923 987.654541 987.6645508
987.6745605 987.6845703 987.6945801 987.7045898
987.7145386 987.7245483 987.7345581 987.7445679
987.7545776 987.7645874 987.7745972 987.7845459
987.7945557 987.8045654 987.8145752 987.824585
987.8345947 987.8445435 987.8545532 987.864563
987.8745728 987.8845825 987.8945923 987.904541
987.9145508 987.9245605 987.9345703 987.9445801
987.9545898 987.9645386 987.9745483 987.9845581
987.9945679 988.0045776 988.0145874 988.0245972
988.0345459 988.0445557 988.0545654 988.0645752
988.074585 988.0845947 988.0945435 988.1045532
988.114563 988.1245728 988.1345825 988.1445923
988.154541 988.1645508 988.1745605 988.1845703
988.1945801 988.2045898 988.2145386 988.2245483
如果我们看一下,我们可以看到前六位有效数字始终精确地遵循该模式(即,每个结果都比其前一个结果正好大 0.01)。正如我们在原始文件中看到的,该值实际上是98x.xx456——double
但是当我们将单精度浮点数转换为十进制时,我们可以看到第 7位数字经常不会被正确读回——因为随后digit 大于 5,它应该四舍五入到 98x.xx46,但有些值不会(例如,第一列中倒数第二个项目是,它会向下舍入而不是向上舍入,所以我们' d 以 98x.xx45 结束,而不是988.154541
46
. 因此,即使该值(如存储的)精确到 7 位(加上一点),但当我们通过转换为十进制并返回该值时,我们不能依赖与任何精确匹配的第七位更多(即使有足够的精度,它会经常出现)。
1. 这基本上意味着 7 位数字,而第 8位数字将比没有更准确一点,但不是很多——例如,如果我们从一个 double 转换,精度1.2345678
的.225
数字意味着最后一个数字将是从那里开始的大约 +/- .775 (而没有.225
精度的数字,它基本上是从那里开始的 +/- 1)。