C++中的大小双值:更精确

Small and large double values in C++: which are more precise?

本文关键字:C++      更新时间:2023-10-16

我使用一个系数进行比较(作为映射键),该系数总是大于1,通常明显大于1。使用反向版本(1/coeff)更精确吗?系数定义了一些尺度,并且是通过将一个二重数除以另一个二重数来获得的,因此可以用两种不同的方式轻松地执行。

在程序设计中,没有太大的区别,但我在某个地方读到,双数值的实现比其他数值增加了小于一个双数值的"比较精度"(比如0<x<1的数字在轴上有更"密集"的填充)。


关于非均匀数密度的一些相关问题:在-1.0和1.0之间的双精度有多少位?

假设你的数字不是整数,那么它不会改善或恶化数字做1/x的实际"精确性"——它会变得更糟,因为你正在做另一个数学运算。因此,仅出于这个原因,我会避免它。

所有浮点数字都有有限的位数来表示尾数。这个值的"精确程度"是1/x还是x没有任何区别。在浮点数字的二进制形式中,就像在十进制形式中一样,我们不能将1/3表示为十进制数字(没有无限的3),所以0.1变成0.099999999999999999999……如果你试着用二进制形式表示它。这个数字是10.1、8.1还是100001.1,以及0.2,都无关紧要,0.4、0.3、0.7、0.8、0.9[以及包含该数值的任何其他数值]。另一方面,0.5、0.25、0.125在二进制中是非常"好"的。

你真的不能通过对浮点值进行数学运算来让它变得"更好"。它只会变得"更糟"(但它真的(1/252)更糟,所以在大多数情况下可能并不重要)。

澄清:

假设我们有值100(精确地用浮点表示,因为它是一个整数,并且所有小于2尾数的整数都以全精度存储,没有错误)。1/100是0.01。如果我们对此执行"十进制到二进制":首先乘以2,直到我们得到一个>=1:的数字

0.01 * 2 = 0.02 
0.02 * 2 = 0.04
0.04 * 2 = 0.08
0.08 * 2 = 0.16
0.16 * 2 = 0.32  // We're getting there 
0.32 * 2 = 0.64
0.64 * 2 = 1.28  // Exponent = -(steps we needed) to get here = -7
                 // Mantissa (M) so far = 1

现在我们有一点。减去1并重复乘以2

0.28*2=0.56//M=1.00.56*2=1.12//M=1.01-减去10.12*2=0.24//M=1.0100.24*2=0.48//M=1.01000.48*2=0.96//M=1.010000.96*2=1.92//M=1.0100000.92*2=1.84//M=1.01000010.84*2=1.76//M=1.01.00000110.76*2=1.52//M=1.0100001110.52*2=1.04/M/1.01000011110.04*2=0.08//M=1.01000011110
0.08*2=0.16//M=1.010000111100

请记住,我们以前见过0.04、0.08的数字,这种情况将永远持续下去。

所以,我们从一个准确的数字开始,这个数字变得不准确了。如果你从一个不准确的数字开始,你就永远不会得到一个准确的数字(处理器的浮点部分——它没有意识到0.0099999999999999999999实际上是0.01——即使它向上/向下舍入实际结果)。

第2版:大数字+小数字的加减法。

现在,把一个很小的数字加到一个很大的数字上,那就另当别论了。这完全取决于所涉及的数字的确切范围。当做加法或减法时,数字会被归一化(就像你在纸上做同样的事情一样)。所以我们得到:

500000 + 0.000000025
 500000.000000000
+     0.000000025
 ----------------
 500000.000000025

现在,问题来了,如果在我们乘以2之后,这个小数字不适合,直到它们具有相同的指数。在这种情况下,0.000000025大约是2-25,500000是~219-19+25=44,所以在53位的范围内,但0.000000025的值可能会稍微四舍五入[我还没有进行转换,看看它是"精确"还是"不精确"的浮点数]。

换句话说,在这种情况下,它是有效的。当然,这对整体价值的影响很小,但我预计这就是目的,或者你会用一个更大的数字来相加。

为了在映射中保留键值对,我建议在小数后固定n位的精度(小数后四舍五入到n位),然后使用字符串或整数(将双值乘以10^n并取整数部分)作为键,以避免混淆和意外。在浮点运算中,1.0000000001和0.9999999999999都是相同的,但作为关键字,它们不是相同的

相关文章:
  • 没有找到相关文章