失去直流精度

Yim*_*ong 13 dc

我想dc用十六进制点处理一些基数为 16 的数字,但我遇到了精度问题。例如,下面,我乘F423F.FD100,无论是十六进制。预期的答案是F423FFD,而不是给出F423FFA.E1,接近但即使在四舍五入后也不够准确。

$ dc
16 d i o F423F.FD 100 * p
F423FFA.E1
Run Code Online (Sandbox Code Playgroud)

我读到这dc是一个无限精度的计算器,无论如何这都不是一个很大的数字。有什么我做错了吗?

感谢您的回答。考虑到 的问题dc,我硬着头皮写了自己的解析器来解析其他基数的实数。如果有人对代码感兴趣,我可以在这里发布。

Ste*_*itt 8

表示为十进制(dc用于转换),这对应于999999.98(四舍五入)×256,255999994.88,十六进制的F423FFA.E1。

所以差异来自于dc的舍入行为:不是计算 256 × (999999 + 253 ÷ 256),这将给出 255999997,而是向下舍入 253 ÷ 256 并将结果相乘。

dc是一个任意精度计算器,这意味着它可以计算到您想要的任何精度,但您必须告诉它那是什么。默认情况下,其精度为 0,这意味着除法仅生成整数值,乘法使用输入中的位数。要设置精度,请使用k(并记住精度始终以十进制数字表示,无论输入或输出基数如何):

10 k
16 d i o
F423FFD 100 / p
F423F.FD0000000
100 * p
F423FFD.000000000
Run Code Online (Sandbox Code Playgroud)

(8 位数的精度就足够了,因为这是您需要用十进制表示 1 ÷ 256 的精度。)

  • 当设置 `k` 时它仍然会失去精度:`10 k 16 dio F423F.FD p` → `F423F.FA`,所以在 `dc` 中使用它们之前,我必须放大所有数字。基本上相当于预先解析它们。 (3认同)
  • @Yimin 是的,不幸的是 `dc` 仅使用位数缩放其输入,这对我来说似乎是一个错误(因为位数是使用输入基数计算的,但应用于十进制值)。 (2认同)

meu*_*euh 6

请注意,仅打印原始数字表明它已四舍五入:

$ dc <<<'16 d i o F423F.FD p'
F423F.FA
Run Code Online (Sandbox Code Playgroud)

您可以通过添加大量尾随零以获得更高的精度来解决它:

$ dc <<<'16 d i o F423F.FD000000 100 * p'
F423FFD.0000000
Run Code Online (Sandbox Code Playgroud)

  • 我会将其标记为已接受的答案。负责维护 `dc` 的人回答说:_为了正确处理非十进制小数位数,需要一个与 dc 和 bc 使用的十进制模型完全不同的模型(如 POSIX 规定的 bc,以及两者的历史传统) ._,所以从技术上讲它可以在 `dc` 中修复,但这可能会破坏 `bc`,因此归类为 WONTFIX。 (2认同)