如何计算浮点型精度,这有意义吗?

问题描述 投票:0回答:1

我在理解浮点类型的精度时遇到问题。msdn writes的精度是6到9位数字。但我注意到精度取决于数字的大小:

  float smallNumber = 1.0000001f;
  Console.WriteLine(smallNumber); // 1.0000001

  bigNumber = 100000001f;
  Console.WriteLine(bigNumber); // 100000000

smallNumber比big更为精确,我了解IEEE754,但我不了解MSDN如何计算精度,这有意义吗?

此外,您也可以使用浮点格式here来表示数字。请在“您输入的”输入中输入100000000的值,然后单击右侧的“ +1”。然后将输入的值更改为1,然后再次单击“ +1”。您可能会看到精度差异。

c# math floating-point ieee-754
1个回答
0
投票

是的,舍入误差前的位数是精度的一种度量,但是您不能仅从2个数字评估精度,因为您可能离舍入阈值更近或更远。

为了更好地了解情况,您需要查看浮点表示方式。

IEEE754 32位浮点存储为:

bool(1bit sign) * integer(24bit mantisa) << integer(8bit exponent)

您可以看到只有整数和位移位。因此,如果您表示的自然数最大为2 ^ 24,那么您将无法完全舍入。较大的数字二进制零填充会从右侧发生,从而导致差异。

对于小数点后的数字,零填充从左开始。但是还有另一个问题,因为在二进制文件中,您不能精确地存储一些十进制数。例如:

0.3 dec = 0.100110011001100110011001100110011001100... bin
0.25 dec = 0.01 bin

如您所见,二进制中的0.3 dec的序列是无限的(就像我们不能以十进制写入1/3),因此,如果将其裁剪为仅24位,则会丢失其余部分,并且该数目不再是您想要的。

如果比较0.30.125,则精确到0.125,而不是0.3,但是0.125比0.3小得多。因此,您的度量是不正确的,除非探索了更接近的值,这些值将覆盖舍入步骤并计算出此类集合的最大差值。例如,您可以比较

1.0000001f
1.0000002f
1.0000003f
1.0000004f
1.0000005f
1.0000006f
1.0000007f
1.0000008f
1.0000009f

并记住fabs(x-round(x))的最大差异,然后做同样的事情>]

100000001
100000002
100000003
100000004
100000005
100000006
100000007
100000008
100000009

然后比较两个差异。

最重要的是,您缺少一件事。那就是打印时的错误,通常更大。数字以二进制为基础存储,因此要打印它们,您需要转换为十进制的基础,其中包括乘以10的乘和除。数字中丢失的位数越多(零填充),打印错误越大。尽可能精确地使用一个技巧,即以十六进制打印数字(无舍入错误),然后根据整数数学将十六进制字符串本身转换为十进制。这比天真浮点打印要准确得多。有关更多信息,请参见相关的质量检查:

dec_digits = floor(log10(2^24)) = floor(7.22) = 7

然而,对于小数点后的数字,它的精确度(对于前几个十进制数字而言)不如四舍五入那么精确。有关更多信息,请参见:

© www.soinside.com 2019 - 2024. All rights reserved.