我使用一个系数进行比较(作为映射键),该系数始终大于 1,通常要大得多。使用反向版本(1/coeff)是否更精确?该系数定义了某种范围,并通过将一个 double 除以另一个数来获得,因此可以通过两种不同的方式轻松执行此操作。
在程序设计中没有太大区别,但我在某处读到, double 的实现比其他 double 值提高了小于一 double 值的“比较精度”(例如 0 < x < 1 数字有更多轴上“密集”堆积)。
关于非均匀数密度的一些相关问题: How many bits of precision for a double between -1.0 and 1.0?
最佳答案
假设你的数字不是整数,那么它不会提高或恶化数字的实际“精确度”来执行 1/x - 它会变得更糟,因为你正在做另一个数学运算。所以仅仅因为这个原因我就会避免它。
所有 float 都有有限的位数来表示尾数。无论是 1/x 还是 x,该值的“精确度”没有任何区别。在 float 的二进制形式中,就像十进制形式一样,我们不能将 1/3 表示为十进制数(没有无限的 3),所以 0.1 变成 0.0999999999999999999999999.... 如果你尝试用以下形式表示它二进制形式。该数字是 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(以 float 准确表示,因为它是一个整数,并且所有小于 2mantissa_bits 的整数都以全精度存储且没有错误)。 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
现在我们有一点了。减一并重复乘以 2
0.28 * 2 = 0.56//M=1.0
0.56 * 2 = 1.12//M=1.01 - 减去 1
0.12 * 2 = 0.24//M=1.010
0.24 * 2 = 0.48//M=1.0100
0.48 * 2 = 0.96//M=1.01000
0.96 * 2 = 1.92//M=1.010000
0.92 * 2 = 1.84//M=1.0100001
0.84 * 2 = 1.76//M=1.01000011
0.76 * 2 = 1.52//M=1.010000111
0.52 * 2 = 1.04//M=1.0100001111
0.04 * 2 = 0.08//M=1.01000011110
0.08 * 2 = 0.16//M=1.010000111100
请记住,我们之前已经见过 0.04、0.08 数字 - 这将永远持续下去。
所以,我们一开始有一个准确的数字,但后来变得不准确了。如果你一开始的数字不准确,你将永远不会得到一个准确的数字(处理器的浮点部分它没有意识到 0.00999999999999999999999999999999999999999 实际上是 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 值可能会稍微四舍五入[我还没有进行转换来查看它是“精确”还是“不精确” float ]。
换句话来说,在这种情况下,它是有效的。当然,它对整体值(value)的影响非常小,但我希望这就是意图,否则您会使用更大的数字来添加。
关于c++ - C++ 中的小 double 值和大 double 值 : which are more precise?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26480910/