Swift:为什么 UInt.max == -1
Swift: Why does UInt.max == -1
如标题所述,lldb 将 UInt.max
的值报告为 -1
的 UInt
,这似乎非常不合逻辑。考虑到 let uint: UInt = -1
甚至不能编译,这怎么可能呢?我看不出有任何方法可以在运行时使 UInt 为负值,因为如果给定负值,初始化程序将崩溃。我想知道 UInt 的实际最大值。
这听起来像是在解释二进制补码和无符号表示下的字面值之间进行转换的实例。
在无符号世界里,二进制数就是二进制数,所以1的位数越多,数字越大,因为不需要对符号进行某种编码。为了表示最大数量的 signed 值,二进制补码编码方案将正值编码为正常值,前提是最极端的位不是 1。如果最极端的位是 1,然后按照 https://en.wikipedia.org/wiki/Two%27s_complement.
中的描述重新解释这些位
如维基百科所示,-1
的二进制补码表示将所有位设置为 1,即最大无符号值。
-1
的Int
值和UInt
值UInt.max
在内存中具有相同的位表示。
你可以看到,如果你这样做:
let i = Int(bitPattern: UInt.max) // i == -1
反方向:
if UInt(bitPattern: Int(-1)) == UInt.max {
print("same")
}
输出:
same
调试器错误地将 UInt.max
显示为带符号的 Int
。它们在内存中具有相同的位表示(0xffffffffffffffff
在 64 位系统上如 iPhone 6 和 0xffffffff
在 32 位系统上如 iPhone 5),并且调试器显然选择将该值显示为 Int
.
如果你这样做,你会看到同样的问题:
print(String(format: "%d", UInt.max)) // prints "-1"
并不是说UInt.max
是-1
,只是说两者在内存中的表示是一样的
要查看 UInt
的最大值,请在应用程序或 Swift 游乐场上执行以下操作:
print(UInt.max)
这将在 64 位系统(例如 Macintosh 或 iPhone 6)上打印 18446744073709551615
,在 32 位系统(例如 iPhone 5).
在lldb中:
(lldb) p String(UInt.max)
(String) $R0 = "18446744073709551615"
(lldb)
如标题所述,lldb 将 UInt.max
的值报告为 -1
的 UInt
,这似乎非常不合逻辑。考虑到 let uint: UInt = -1
甚至不能编译,这怎么可能呢?我看不出有任何方法可以在运行时使 UInt 为负值,因为如果给定负值,初始化程序将崩溃。我想知道 UInt 的实际最大值。
这听起来像是在解释二进制补码和无符号表示下的字面值之间进行转换的实例。
在无符号世界里,二进制数就是二进制数,所以1的位数越多,数字越大,因为不需要对符号进行某种编码。为了表示最大数量的 signed 值,二进制补码编码方案将正值编码为正常值,前提是最极端的位不是 1。如果最极端的位是 1,然后按照 https://en.wikipedia.org/wiki/Two%27s_complement.
中的描述重新解释这些位如维基百科所示,-1
的二进制补码表示将所有位设置为 1,即最大无符号值。
-1
的Int
值和UInt
值UInt.max
在内存中具有相同的位表示。
你可以看到,如果你这样做:
let i = Int(bitPattern: UInt.max) // i == -1
反方向:
if UInt(bitPattern: Int(-1)) == UInt.max {
print("same")
}
输出:
same
调试器错误地将 UInt.max
显示为带符号的 Int
。它们在内存中具有相同的位表示(0xffffffffffffffff
在 64 位系统上如 iPhone 6 和 0xffffffff
在 32 位系统上如 iPhone 5),并且调试器显然选择将该值显示为 Int
.
如果你这样做,你会看到同样的问题:
print(String(format: "%d", UInt.max)) // prints "-1"
并不是说UInt.max
是-1
,只是说两者在内存中的表示是一样的
要查看 UInt
的最大值,请在应用程序或 Swift 游乐场上执行以下操作:
print(UInt.max)
这将在 64 位系统(例如 Macintosh 或 iPhone 6)上打印 18446744073709551615
,在 32 位系统(例如 iPhone 5).
在lldb中:
(lldb) p String(UInt.max)
(String) $R0 = "18446744073709551615"
(lldb)