我一直在尝试(或搞乱)非常大的数字,例如 2^63 和 2^64,它们分别是 C++ 中普通有符号 long long 和无符号 long long 可能存在的值的数量。
我们知道,
2^64 = 18446744073709551616
2^64 - 2 = 18446744073709551614
所以如果我们减去这些数字,答案应该是
2
。
但是当我在谷歌上搜索
18446744073709551616 - 18446744073709551614
时,得到的答复是0
。对于许多像 0
这样大的数字,我会得到 18446744073709551611 - 18446744073709551615
。
有人可以解释为什么会发生这种情况吗?
由于浮点精度限制,Google 计算器在此计算中返回 0。虽然 Google 计算器可以处理大数,但它使用 IEEE 754 浮点标准,该标准对于极大整数的精度有限。
当两个非常大的数字靠近时(例如 18446744073709551616 和 18446744073709551614),它们的差异可能小于精度阈值。在这种情况下,小差值 (2) 将向下舍入为零,从而有效地将两个数字视为相等。
为什么会发生这种情况:
浮点精度:浮点格式无法精确表示超过 2^53 的每个大整数,从而导致舍入误差。 接近大数:对于接近的大值,由于最后几位的精度有限,浮点算术将它们视为相同的值,从而导致 0 差异。 差异较大的示例:如果您尝试 184467440737095516161 - 18446744073709551614,结果是准确的,因为差异足够大,可以在浮点精度内表示。
解决方案:
要获得大且接近的整数的精确结果,请使用支持任意精度算术的工具或编程环境(例如 Python 的 int 或 JavaScript 的 BigInt),这样可以避免舍入并可以处理任何大小的精确计算。