5

众所周知decimal fractions(如 0.1),当存储为floating point(如 double 或 float)时,将在内部以“二进制格式”(IEEE 754)表示。并且有些小数部分不能直接用二进制格式表示。

我不明白的是这种“转换”的精确度:

1.)浮点本身可以​​具有精度(即“显着”)?

2.) 而且从十进制小数到二进制小数的转换也会有精度损失?

问题:

从小数转换为浮点小数时,最坏情况下的精度损失是多少(对于“所有”可能的小数)?

(我想知道这一点的原因是,在将小数与二进制/浮点分数进行比较时,我需要考虑精度......以确定两个数字是否相同。我希望这个精度尽可能精确/精确尽可能(decimal fraction == binary fraction +/- precision)

示例(仅假设)

0,1 dec => 0,10000001212121212121212 (binary fraction double) => precision loss 0,00000001212121212121212
0,3 dec => 0,300000282828282 (binary fraction double) => precision loss  0,000000282828282
4

5 回答 5

4

我并不完全清楚您的目标是什么,但您可能会对以下论文感兴趣,该论文讨论了二进制/十进制转换中涉及的许多准确性问题,包括困难案例列表。

弗恩·帕克森和威廉·卡汉。用于测试 IEEE 十进制-二进制转换的程序。1991 年 5 月 22 日 http://www.icir.org/vern/papers/testbase-report.pdf

于 2011-08-24T02:33:37.003 回答
3

浮点数将变得越来越不准确(正向和负向)。这是因为浮点值是指数格式。

但是,无论它有多大,小数点使用的小数位数越多,它就会变得越来越精确。

因此,最差的精度差异将是您使用的任何浮点类型的数值限制。

于 2011-08-24T02:12:56.640 回答
1

由于我们从小就被教导数数的方式,很难完全理解二进制分数的精确特性。问题是分数只能是计数系统的功率。说起来似乎很明显,但基本问题是十进制将事物分为十,而二进制将事物分为二(半)。

大多数时候,在计算中有两次需要浮点值:当它是货币值时,当它不是。后者的范围可以从来自旋转轴上的编码器的输入到虚拟空间中的位置以用于处理到图形引擎。小数值是二进制的没有问题,因为它确实是一个小数值。这也是 FPU 在几年前开始流行于 3D 图形的部分原因。

问题在于表示货币,其中小数部分实际上是离散的十进制单位。在现实世界中,您可以拥有 0.01 美元(取决于它是哪一美元!),但这很难用二进制准确表示。这就是为什么你永远不应该使用二进制浮点作为货币。

如果您在十进制和二进制浮点之间进行转换并尝试进行比较,我会看看您为什么要进行转换以及比较应该达到什么目的。

于 2011-08-24T02:33:20.277 回答
1

如果十进制值落入可表示的浮点值范围内,并且您的语言/实现具有正确舍入的转换(很多可以,有些不可以),则此类转换的错误以 1/2 为界连续浮点数之间的距离,或“ulp”(最后位置的单位)。

ulp的相对大小在 2 的精确幂和下一个更大的数字之间最大,因此当输入刚好小于 1 + 1/2 ulp 时,十进制和双精度之间的最大相对转换误差,或者值按 2 的幂缩放。这种值的一个例子是:

1.0000000000000001110223024625156540423631668090820312

(这几乎无限小于 1 + 2^-53)。

由于转换产生的误差有一个相对界限,显然,当我们将该值按 2 次方放大时,绝对误差会变大。

当然,如果一个数字超出了可表示值的范围(太大或太小),那么所有的精度都会丢失。转换,比如说1e400收益doubleinfinity;没有我们实际输入的痕迹。同样,转换1e-400double产生零。

于 2011-08-24T02:38:27.107 回答
0

数字越大,精度损失就越高(但它可能正是您指定的数字)。

您不仅在 java 中将非常小的数字存储为浮点数或双精度数,而且还将非常大的数字存储为 9*10^105。

而且我希望这种精度尽可能严格/精确

您可以选择 BigDecimal,您可以在其中指定您希望获得的精确度,但当然您会受到 RAM、CPU 时间和 JVM 的限制。

您只对绝对精度感兴趣,还是对相对精度感兴趣?

比较以下精度的差异:

a = 100000000000000,0000000000000001 
b = 100000000000000,0000000000000002

layoutHonkyTonkA= 0,0000000000000001 
layoutHonkyTonkB= 0,0000000000000002

绝对精度差是一样的,但是相对精度差是很大的。

于 2011-08-24T03:29:07.273 回答