对于我正在学习的内容,一旦我将浮点值转换为十进制值,我需要的“有效数字”是一个固定数字(例如,17为double)。 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;
}
将正确地“显示”17个值:
1.2345678912345679
123.45678912345679
123456789123.45679
但如果我提高cout
的精确度(即std::cout.precision(100)
),我可以看到17范围之后还有其他数字:
1.2345678912345678934769921397673897445201873779296875
123.456789123456786683163954876363277435302734375
123456789123.456787109375
为什么要忽略它们?它们也存储在变量/ double中,因此它们将在稍后影响整个“数学”(除法,乘法,求和等)。
“有效数字”是什么意思?还有其他......
答案 0 :(得分:1)
请注意,浮点值不是实数。值之间存在间隙,所有这些额外数字虽然对实数有意义,但并不反映浮点值的任何差异。将浮点值转换为文本时,使用std::numeric_limits<...>::max_digits10
数字可确保您可以将文本字符串转换回浮点并获取原始值。额外的数字不会影响结果。
当您要求更多数字时,您看到的额外数字是转换算法尝试执行您所要求的结果。该算法通常只是提取数字直到达到所需的精度;它可以写成在写入max_digits10 digits
之后开始输出零,但这是一个没有人烦恼的额外复杂因素。这不会有帮助。
答案 1 :(得分:1)
只是为了添加 Pete Becker 的答案,我认为你会混淆找到二进制尾数的精确十进制表示的问题,找到某些十进制表示唯一表示二进制尾数的问题(给定一些固定的舍入方案)。
现在,关于第一个问题,你总是需要有限数量的十进制数来准确表示二进制尾数(因为2除以10)。
例如,您需要18个十进制数字完全代表二进制1.0000000000000001
,以十进制为1.00000762939453125
。
但是您只需要17个数字就可以将其唯一地表示为1.0000076293945312
,因为没有其他数字具有精确值1.0000076293945312xyz...
,其中0 <= x <5可以作为double存在(更确切地说,下一个和先前可准确表示的值为1.0000076293945314720446049250313080847263336181640625
和1.0000076293945310279553950749686919152736663818359375
)。
当然,不意味着给定一些十进制数,你可以忽略17日之后的所有数字;它只是意味着如果你应用相同的舍入方案用于在第17个位置产生小数并将其分配回一个双倍,你将获得相同的原始双倍。
答案 2 :(得分:1)
你能帮助我理解浮点数学中“有效数字”的含义吗?
对于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
当关注十进制有效数字和FP类型如double
时。问题通常是&#34;需要或关注多少十进制有效数字?&#34;
几乎所有C FP实现都使用二进制编码,这样所有有限FP都是精确 2的幂和。每个有限FP exact 。通用编码为大多数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 十进制有效数字。
这意味着什么&#34;有效数字&#34;?
存在有效数字的各种含义,但对于C,有两种常见的含义:
十进制有效数字的数量,double
的文字值按预期转换为所有double
。通常为15. C将其指定为DBL_DIG
且必须至少为10.
十进制有效数字的数量,需要打印文本值double
以区别于另一个double
。这通常是17. C将其指定为DBL_DECIMAL_DIG
且必须至少为10.
为什么要忽略它们?
这取决于编码目标。很少是所需的确切值的所有数字。 (DBL_TRUE_MIN
可能有752个。)对于大多数应用程序,DBL_DECIMAL_DIG
就足够了。在选定的应用中,DBL_DIG
会这样做。所以通常是,忽略17点以后的数字不会导致问题。