【问题标题】:Decimal fraction to binary with precision小数到二进制精度
【发布时间】:2020-04-17 03:52:18
【问题描述】:

考虑以下分数:

9.8765

如何在不丢失任何值的情况下将其转换为精确的浮点二进制?

现在考虑以下分数

9.87654321

再次,我如何将其转换为浮点二进制而不丢失其值。

我想确定从浮点二进制值重构分数需要多少精确的二进制位。

这只是一个示例,我希望对具有许多数字的大分数执行操作(例如 9.876543210192283647582910)。

如果该示例使用 Java,请欣赏。

谢谢!

【问题讨论】:

  • 没有与您的任何示例完全相等的二进制分数,因此转换为二进制浮点格式会产生舍入错误。 9.876500000000000005684341886080801486968994140625 是最接近 9.8765 的 IEEE 754 64 位二进制浮点数。这对你的目的来说足够近了吗?
  • 你的意思是在分数和二进制之间转换时总是会出现舍入错误?可以用更多的位数来抵消吗?
  • 每个二进制分数都有一个精确的十进制分数。例如,每个 Java double 数字都可以精确地转换为 BigDecimal。反过来说,更多的比特将允许更接近的近似值。这就是为什么我问 9.87650000000000005684341886080801486968994140625 是否足够接近。
  • 数字⅓不能用十进制写成有限位数;它是 .33333333……永远持续下去。类似地,9.8765 不能以有限位数的二进制形式写入。当你做算术转换它时,总是有一个残差继续到下一个位置。如果你知道它有多少位,你可以用二进制足够准确地表示一个十进制数字,你可以恢复原始数字。该数字会有一个小错误,但它与原始十进制数字足够接近,您知道它来自哪个十进制数字。
  • 但是,当您对这些数字进行算术运算时,它们的错误可能会复合(或可能取消)。然后可能不再可能确定哪个十进制数字是您通过十进制算术而不是二进制算术获得的数字。如果要进行十进制运算,一般应该使用十进制运算的软件,比如BigDecimal。如果这不适合您的目的,您需要在问题中添加信息,解释您要解决的完整问题。

标签: floating-point binary fractions


【解决方案1】:

一般来说,一个有理数可以表示为一个基数 R 分数,当且仅当,在其最低条件下,分母的所有质因数都是 R 的因数。

将此应用于十进制,当且仅当在其最低项中 2 和 5 是分母的唯一质因数时,有理数具有终止的十进制扩展。因此 13/40 有一个终止的小数扩展,而 1/3 没有。

对于二进制分数,这意味着将整数 A 和 B 的有理数表示为 A/2B。因为 2 是 10 的因数,所以所有二进制分数都可以表示为小数。 5 不是 2 的因数,所以 1/10 等小数部分不能表示为二进制小数。

作为普通 Java double 的精确表示还有其他条件。 B 必须在 [-1022, 1023] 范围内,并且 A 必须有不超过 53 个有效位。还有其他次正规数,指数为 -1023。增加位数会放宽这些限制,但仍不允许像 1/10 这样的数字以二进制浮点数精确表示。

两种最常见的解决方案是接受它,或者切换到BigDecimal

9.87650000000000005684341886080801486968994140625 非常非常接近 9.8765。对于长度和重量等物理量,即使使用良好的实验室设备,测量误差也将超过转换误差。当然,有些算法在后续计算中会因为四舍五入而累积较大的误差。

BigDecimal 对于带有终止十进制扩展的数字特别有用。财务计算通常必须处理 0.01 或 0.001 的精确倍数。尽管它允许任意精度,直到可用内存,但它无法避免所有舍入误差。没有正好等于 1/3 的BigDecimal

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-08-14
    • 1970-01-01
    • 2017-05-30
    • 2015-10-14
    • 1970-01-01
    • 2016-01-31
    • 1970-01-01
    • 2011-02-14
    相关资源
    最近更新 更多