小数点后19位及以后的数学精度
我有相同的数据集并且运行相同的代码,但有时我在小数点后 19 位及以后得到不同的结果。虽然对于小于 0.0001 的数字这不是我很关心的问题,但它让我想知道小数点后 19 位是否是 Raku 的精度限制?
Word 104 differ:
0.04948872986571077 19 chars
0.04948872986571079 19 chars
Word 105 differ:
0.004052062278212545 20 chars
0.0040520622782125445 21 chars
回答
TL; DR看到该文档的优秀Numerics的页面。
(在我写下以下答案之前,我已经忘记了那个页面。考虑这个答案至多是该页面几个方面的简要总结。)
这有两个方面。内部精度和印刷精度。
100%内部精度,直到 RAM 耗尽
Raku 支持任意精度的数字类型。引用维基百科的相关页面:
精度位数仅受主机系统可用内存的限制
您可以指示 Raku 使用其任意精度类型之一。[1]如果你这样做,它将保持 100% 的精度,直到它用完 RAM。
| 任意精度型 | 对应的类型检查[2] | 该类型值的示例 |
|---|---|---|
Int |
my Int $foo ... |
66174449004242214902112876935633591964790957800362273 |
FatRat |
my FatRat $foo ... |
66174449004242214902112876935633591964790957800362273 / 13234889800848443102075932929798260216894990083844716 |
因此,您可以获得整数和分数的任意内部精度(包括任意精度小数)。
有限的内部精度
如果您不指示 Raku 使用任意精度数字类型,它会尽力而为,但最终可能会切换到有限精度。例如,如果您使用的公式计算 aRat并且数字的分母超过 64 位,Raku 将放弃 100% 的精度。[1]
Raku 的回退有限精度数字类型是Num:
在大多数平台上,[a
Num是] IEEE 754 64 位浮点数,又名“双精度”。
引用该标准的维基百科页面:
使用浮点数……当需要更宽的范围时……即使以精度为代价。
53 位有效数精度提供 15 到 17 位有效十进制数字精度(2?53 ? 1.11 × 10?16)。
印刷精度
与内部精度不同的是数字的字符串化。
(正是在这个阶段,我想起了这个答案开头链接的 Numerics 文档页面。)
引用印刷原理:
请记住,像
say或put...这样的输出例程可能会选择将 a 显示Num为一个Int或一个Rat数字。要输出更明确的字符串,请使用raku方法或 [对于有理数].nude
脚注
[1]您可以通过表达式中单个数字的类型以及数字运算结果的类型来控制数字表达式的类型,而这又取决于数字的类型。例子:
-
1 + 2是3,一个Int,因为两个1和2是IntS,并且a + b是Int如果同时a和b被IntS; -
1 / 2是不是一个Int虽然双方甚至1和2单独IntS中,但反而1/2又名0.5,一Rat。 -
1 + 4 / 2将打印为3,但由于数字感染性,在3内部是 aRat,而不是 an 。Int
[2]如果您尝试分配或绑定一个不是您指定为变量类型约束的数字类型的值,则强制执行所做的只是生成一个运行时错误。强制执行并不意味着 Raku 会为您转换数字。您必须编写公式以确保得到的结果是您想要的。[1]你可以使用强制——但强制不能恢复已经失去的精度。