c++ - C++ 中的小 double 值和大 double 值 : which are more precise?

标签 c++ double

我使用一个系数进行比较(作为映射键),该系数始终大于 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/

相关文章:

c++ - 指针访问冲突问题

c++ - 如何在使用模板的类中包含另一个类?

java - 需要 java double 才能不向下舍入

java - 双倍乘法与加法速度

c - 带有双格式问题的 Printf

c++ - Arduino Only 只读取一个字符。

c++ - 在 MessageBoxW c++ 中显示一个变量

c++ - 当输入声明为 double [C++] 时检查输入是否为空

java - 我制作了一个 CLI 计算器,我想知道,如何让程序无限期地接受数字,直到用户输入停止命令?

c++ - C#'s "其中 T : type"in C++