你能帮我理解 "significant digits" 在浮点数学中的含义吗?
Can you help me to understand what "significant digits" means in floating point math?
就我正在学习的内容而言,一旦我将浮点值转换为十进制值,我需要的 "significant digits" 就是一个固定数字(例如,17 表示双精度)。 17个总数:小数点前后分隔符。
例如这段代码:
typedef std::numeric_limits<double> dbl;
int main()
{
std::cout.precision(dbl::max_digits10);
//std::cout << std::fixed;
double value1 = 1.2345678912345678912345;
double value2 = 123.45678912345678912345;
double value3 = 123456789123.45678912345;
std::cout << value1 << std::endl;
std::cout << value2 << std::endl;
std::cout << value3 << std::endl;
}
将正确 "show me" 17 个值:
1.2345678912345679
123.45678912345679
123456789123.45679
但是如果我提高 cout
的精度(即 std::cout.precision(100)
),我可以看到在 17 范围之后还有其他数字:
1.2345678912345678934769921397673897445201873779296875
123.456789123456786683163954876363277435302734375
123456789123.456787109375
为什么要忽略它们?它们也存储在 variables/double 中,因此它们稍后会影响整个 "math"(除法、乘法、求和等)。
"significant digits"是什么意思?还有其他...
请记住,浮点值是不是实数。这些值之间存在差距,所有这些额外的数字虽然对实数有意义,但并不反映浮点值的任何差异。当您将浮点值转换为文本时,具有 std::numeric_limits<...>::max_digits10
位可确保您可以将文本字符串转换回浮点值并获得原始值。多余的数字不影响结果。
当您要求更多数字时,您看到的额外数字是转换算法试图按照您的要求执行的结果。该算法通常只是不断提取数字,直到达到所需的精度;它可以写成在写入 max_digits10 digits
后开始输出零,但这是一个额外的复杂问题,没有人会为此烦恼。它不会真的有帮助。
只是添加到 Pete Becker 的回答中,我认为你混淆了找到 exact 十进制表示的问题二进制尾数,问题是找到 some 十进制表示 uniquely 表示二进制尾数(给定一些固定的舍入方案)。
现在,关于第一个问题,您总是需要有限数量的十进制数字来准确表示二进制尾数(因为 2 除以 10)。
例如,你需要18位十进制数才能正好表示二进制1.0000000000000001
,即十进制的1.00000762939453125
。
但是你只需要 17 位数字就可以将它唯一地表示为 1.0000076293945312
因为没有其他数字具有精确值 1.0000076293945312xyz...
其中 0<=x<5 可以作为双精度存在(更准确地说, next 和 prior 完全可表示的值是 1.0000076293945314720446049250313080847263336181640625
和 1.0000076293945310279553950749686919152736663818359375
).
当然,这并不意味着给定一些十进制数,您可以忽略第 17 位之后的所有数字;这只是意味着如果您应用相同的舍入方案用于在第 17 个位置生成小数并将其分配回双精度,您将获得相同的原始双精度。
Can you help me to understand what “significant digits” means in floating point math?
对于 FP 数字,如数学实数,有效数字 是不以 0
开头的值的前导数字,然后根据上下文,到 1) 小数点,2) 最后一个非零数字,或 3) 最后一个打印的数字。
123. // 3 significant decimal digits
123.125 // 6 significant decimal digits
0.0078125 // 5 significant decimal digits
0x0.00123p45 // 3 significant hexadecimal digits
123000.0 // 3, 6, or 7 significant decimal digits depending on context
当关注 十进制有效数字 和 double
等 FP 类型时。问题通常是 "How many decimal significant digits are needed or of concern?"
几乎所有 C FP 实现都使用 binary 编码,这样所有有限 FP 都是 exact 2 的幂和。每个有限 FP 准确。通用编码提供大多数 double
有 53 个二进制数字是它的有效数字 - 所以 53 有效二进制数字 。这如何显示为小数通常是混淆的根源。
// Example 0.1 is not an exact sum of powers of 2 so a nearby value is used.
double x = 0.1;
// x takes on the exact value of
// 0.1000000000000000055511151231257827021181583404541015625
// aka 0x1.999999999999ap-4
// aka base2: 0.000110011001100110011001100110011001100110011001100110011010
// The preceding and subsequent doubles
// 0.09999999999999999167332731531132594682276248931884765625
// 0.10000000000000001942890293094023945741355419158935546875
// 123456789012345678901234567890123456789012345678901234567890
从上面看,可以说 x
有超过 50 十进制有效数字 。然而,该值匹配预期的 0.1 到 16 十进制有效数字。或者,由于前面和后面可能的 double
值在第 17 位不同,可以说 x
有 17 十进制有效数字 .
What does it means "significant digits"?
存在有效数字的各种含义,但对于 C,2 个常见的含义是:
十进制有效数字 的double
文本值按预期转换为所有double
的数目。这通常是 15。C 将其指定为 DBL_DIG
并且必须至少为 10.
文本值 double
需要打印的 十进制有效数字 的数量,以区别于另一个 double
。这通常是 17。C 将其指定为 DBL_DECIMAL_DIG
并且必须至少为 10.
Why should ignore them?
这取决于编码目标。很少需要精确值的所有数字。 (DBL_TRUE_MIN
可能有 752 个。)对于大多数应用程序,DBL_DECIMAL_DIG
就足够了。在 select 个应用程序中,DBL_DIG
即可。所以通常,忽略 17 之后的数字不会造成问题。
就我正在学习的内容而言,一旦我将浮点值转换为十进制值,我需要的 "significant digits" 就是一个固定数字(例如,17 表示双精度)。 17个总数:小数点前后分隔符。
例如这段代码:
typedef std::numeric_limits<double> dbl;
int main()
{
std::cout.precision(dbl::max_digits10);
//std::cout << std::fixed;
double value1 = 1.2345678912345678912345;
double value2 = 123.45678912345678912345;
double value3 = 123456789123.45678912345;
std::cout << value1 << std::endl;
std::cout << value2 << std::endl;
std::cout << value3 << std::endl;
}
将正确 "show me" 17 个值:
1.2345678912345679
123.45678912345679
123456789123.45679
但是如果我提高 cout
的精度(即 std::cout.precision(100)
),我可以看到在 17 范围之后还有其他数字:
1.2345678912345678934769921397673897445201873779296875
123.456789123456786683163954876363277435302734375
123456789123.456787109375
为什么要忽略它们?它们也存储在 variables/double 中,因此它们稍后会影响整个 "math"(除法、乘法、求和等)。
"significant digits"是什么意思?还有其他...
请记住,浮点值是不是实数。这些值之间存在差距,所有这些额外的数字虽然对实数有意义,但并不反映浮点值的任何差异。当您将浮点值转换为文本时,具有 std::numeric_limits<...>::max_digits10
位可确保您可以将文本字符串转换回浮点值并获得原始值。多余的数字不影响结果。
当您要求更多数字时,您看到的额外数字是转换算法试图按照您的要求执行的结果。该算法通常只是不断提取数字,直到达到所需的精度;它可以写成在写入 max_digits10 digits
后开始输出零,但这是一个额外的复杂问题,没有人会为此烦恼。它不会真的有帮助。
只是添加到 Pete Becker 的回答中,我认为你混淆了找到 exact 十进制表示的问题二进制尾数,问题是找到 some 十进制表示 uniquely 表示二进制尾数(给定一些固定的舍入方案)。
现在,关于第一个问题,您总是需要有限数量的十进制数字来准确表示二进制尾数(因为 2 除以 10)。
例如,你需要18位十进制数才能正好表示二进制1.0000000000000001
,即十进制的1.00000762939453125
。
但是你只需要 17 位数字就可以将它唯一地表示为 1.0000076293945312
因为没有其他数字具有精确值 1.0000076293945312xyz...
其中 0<=x<5 可以作为双精度存在(更准确地说, next 和 prior 完全可表示的值是 1.0000076293945314720446049250313080847263336181640625
和 1.0000076293945310279553950749686919152736663818359375
).
当然,这并不意味着给定一些十进制数,您可以忽略第 17 位之后的所有数字;这只是意味着如果您应用相同的舍入方案用于在第 17 个位置生成小数并将其分配回双精度,您将获得相同的原始双精度。
Can you help me to understand what “significant digits” means in floating point math?
对于 FP 数字,如数学实数,有效数字 是不以 0
开头的值的前导数字,然后根据上下文,到 1) 小数点,2) 最后一个非零数字,或 3) 最后一个打印的数字。
123. // 3 significant decimal digits
123.125 // 6 significant decimal digits
0.0078125 // 5 significant decimal digits
0x0.00123p45 // 3 significant hexadecimal digits
123000.0 // 3, 6, or 7 significant decimal digits depending on context
当关注 十进制有效数字 和 double
等 FP 类型时。问题通常是 "How many decimal significant digits are needed or of concern?"
几乎所有 C FP 实现都使用 binary 编码,这样所有有限 FP 都是 exact 2 的幂和。每个有限 FP 准确。通用编码提供大多数 double
有 53 个二进制数字是它的有效数字 - 所以 53 有效二进制数字 。这如何显示为小数通常是混淆的根源。
// Example 0.1 is not an exact sum of powers of 2 so a nearby value is used.
double x = 0.1;
// x takes on the exact value of
// 0.1000000000000000055511151231257827021181583404541015625
// aka 0x1.999999999999ap-4
// aka base2: 0.000110011001100110011001100110011001100110011001100110011010
// The preceding and subsequent doubles
// 0.09999999999999999167332731531132594682276248931884765625
// 0.10000000000000001942890293094023945741355419158935546875
// 123456789012345678901234567890123456789012345678901234567890
从上面看,可以说 x
有超过 50 十进制有效数字 。然而,该值匹配预期的 0.1 到 16 十进制有效数字。或者,由于前面和后面可能的 double
值在第 17 位不同,可以说 x
有 17 十进制有效数字 .
What does it means "significant digits"?
存在有效数字的各种含义,但对于 C,2 个常见的含义是:
十进制有效数字 的
double
文本值按预期转换为所有double
的数目。这通常是 15。C 将其指定为DBL_DIG
并且必须至少为 10.文本值
double
需要打印的 十进制有效数字 的数量,以区别于另一个double
。这通常是 17。C 将其指定为DBL_DECIMAL_DIG
并且必须至少为 10.
Why should ignore them?
这取决于编码目标。很少需要精确值的所有数字。 (DBL_TRUE_MIN
可能有 752 个。)对于大多数应用程序,DBL_DECIMAL_DIG
就足够了。在 select 个应用程序中,DBL_DIG
即可。所以通常,忽略 17 之后的数字不会造成问题。