これらは、わずかに異なる 2 つのことについて話しています。
7.225 1桁は、数値を内部に格納できる精度です。たとえば、倍精度数で計算を行った場合 (つまり、15 桁の精度で開始した場合)、それを単精度数に丸めた場合、その時点で残っていた精度はおおよそ次のようになります。 7桁。
6桁は、10進数の文字列から浮動小数点数への往復変換によって維持できる精度について話し、次に別の10進数の文字列に戻します。
したがって、1.23456789
文字列のような数値から始めて、それを float32 に変換し、結果を文字列に戻すと仮定しましょう。これを行うと、6 桁が正確に一致することが期待できます。ただし、7 桁目は丸められている可能性があるため、必ずしも一致するとは限りません (ただし、元の文字列の +/- 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
これを調べると、最初の 6 桁の有効桁数が常に正確にパターンに従っていることがわかります (つまり、各結果は前の結果よりも正確に 0.01 大きい)。元の でわかるようにdouble
、値は実際には 98x.xx456 ですが、単精度浮動小数点数を 10 進数に変換すると、7桁目が頻繁に正しく読み取られないことがわかります。桁が 5 より大きい場合、98x.xx46 に切り上げますが、一部の値は切り上げません (たとえば、最初の列の最後から 2 番目の項目は で988.154541
あり、切り上げではなく切り捨てになるため、 d の代わりに 98x.xx45 になります46
. そのため、(保存された) 値が 7 桁 (プラス少し) の精度であっても、10 進数への変換とその逆の変換によって値を往復するまでには、その 7 桁目が正確に一致することに依存することはできません。より多く(十分な精度があるにもかかわらず、そうでない場合よりもはるかに頻繁になります)。
1. これは基本的に 7 桁を意味し、8桁目は何もないよりは少し正確ですが、それほど多くはありません。そこから始まったものの約+/- .775になります(精度の桁がなければ、基本的にそこから始まったものの+/- 1になります)。
1.2345678
.225
.225