首页 > 解决方案 > 如果我们将格式更改为类似于双 IEEE 754-1985 的格式,我们能否消除数字的浮点错误?

问题描述

目前 IIRC,当前显示浮点数的方法是将它们显示为1/2 + 1/4 + 1/8 .... 但是,如果我们改变对浮点数的处理方法,使得任何浮点数实际上都是一个普通整数,并用一系列 0 填充回来。每个数字都必须更大,类似于 62 位双精度数。

对于 62 位双精度数,我们为指数保留 11 位,为实际数字保留 53 位。现在,我们可以做的是让一个数字代表我们用它填充的“零”的数量。在这个例子中,我们可以有 11 个作为填充位,这意味着我们有(2 ^ 11) - 1一个 53 位数字的精度位数。

假设我想显示0.4,目前在 Python 中我们知道0.4有浮点问题,例如,

>>> import decimal
>>> decimal.Decimal(0.4)
Decimal('0.40000000000000002220446049250313080847263336181640625')

但是使用我的编码,这不会发生,为什么?因为我可以4用传统的二进制来表示数字,100而超过零的数量可以表示为二进制数101. 这意味着我可以用数字表示数字0.4而没有任何浮点问题,

0 00000000001 00000000000000000000000000000000000000000000000000100

第一位保留用于符号,接下来11用于零填充和53数字。它需要更多位,但我现在可以2 ^ 11准确地表示一个长度为位数的数字。不仅如此,维基百科页面还建议 C++ double 仅16数字准确,这意味着我的2048 - 16数字更准确!

标签: floating-pointprecisionfloating-accuracy

解决方案


您特别提到 IEEE 754-1985 很奇怪,因为IEEE 754-2008已经引入了十进制算术。与 double 相比,您提出的方案的范围要小得多,这使得它不适合科学计算。事实上,小数计算经常被保留用于财务计算,因为即使在休闲生活中,我们也很少处理绝对精度。我们可以在田间饲养 3 头奶牛,但它们的体重呢?他们的价格可能看起来绝对准确,但在你计算出你所欠的销售税之后呢?

IEEE 754-2008 引入了decimal64,其中最大有效数字仍然是16。即使在科学领域(十进制算术不合适),NASA 的星际 飞行也依赖于 pi 的简陋 3.141592653589793 ,在小数点后第 15 位。哦,但你想要财务计算?好吧,.NET 使用 128 位小数,其精度为28-29位,世界各地的金融机构都乐于采用 .NET 小数,而无需打扰其他花哨的方案。decimal128存在并具有 34 位精度。

此外,您的方案不可能有 2048-16 位的精度。您只为数字分配 53 位,而 .NET Decimal 分配了96 位,因为您的方案非常相似

Decimal 值的二进制表示由 1 位符号、96 位整数和用于划分 96 位整数并指定它的哪一部分是小数部分的比例因子组成。比例因子隐含地是数字 10,升为从 0 到 28 的指数。

准确度将处于 decimal64 的 16 位(使用 50 位)和 .NET Decimal 的 28 位之间的低端。在实践中,普通用户每天不会进行数十亿的财务计算,因此消费者的 CPU 不会费心采用 IEEE 754-2008,而且由于唯一要求他们购买 IBM 的 Power CPU 以固定在他们的服务器中,所以不要期待本机硬件和集成(如标准,而不是额外的库)语言支持很快就会出现


推荐阅读