基础:为什么 Int64.max 和 Double(Int64.max) 在 Swift iOS SDK 中打印 2 个完全不同的值

Mih*_*hta 2 foundation ios swift

这是我的 Swift 代码

print("\(Int64.max)")
print("\(Double(Int64.max))")
Run Code Online (Sandbox Code Playgroud)

它产生以下输出

9223372036854775807

9.223372036854776e+18

为什么两个值完全不同 9.223372036854776e+18 - 9223372036854775807 = 193 FYI

Swe*_*per 5

您在输出中看到的值Double只是一些有效数字的近似值。我们可以看到更重要的数字String(format:)

print(String(format: "%.1f", Double(Int64.max)))
Run Code Online (Sandbox Code Playgroud)

这打印:

9223372036854775808.0
Run Code Online (Sandbox Code Playgroud)

所以实际上,差异并不像您声称的那么大(193)。仅仅相差1。

为什么会有差异?

Double使用浮点表示形式存储值。它可以表示很大范围的数字,但不能表示该范围内的每个数字。Double使用 53 位尾数、1 位符号位和 11 位来存储指数。尾数代表数字的有效数字,指数告诉您小数点放在哪里。小数点一侧的所有内容都代表 2 的正幂,而另一侧的所有内容都代表 2 的负幂。例如:

0.1010000    0010
  mantissa    exponent
Run Code Online (Sandbox Code Playgroud)

指数表示将小数点向右移动 3 次,因此尾数变为010.10000。左边的1代表2,右边的1代表一半(2^-1),所以这个浮点数代表数字2.5

为了表示Int64.max(2^63-1),需要63位尾数全部为1,指数中的值为63。但是Double没有那么多位尾数!所以只能近似。Int64.max + 1实际上可以用 a 表示Double,因为它等于2^63。您只需要尾数中的 11后跟 520即可存储指数64。这就是我们Double所做的。