对 64 位 UInt 右移充当有符号移位感到困惑
Puzzled with 64-bit UInt right shift acting as signed shift
为什么右移行为如下?
let a: UInt = 0x6177206d, b: UInt = 0x9e3779b1
let m: UInt = a * b
print("""
let m = \(String(format:"%x", a)) * \(String(format:"%x", b)) = \(String(format:"%x", m))
m>>4=\(String(format:"%x", m >> 4))
m>>8=\(String(format:"%x", m >> 8))
m>>16=\(String(format:"%x", m >> 16))
m>>32=\(String(format:"%x", m >> 32))
""")
生产:
let m = 6177206d * 9e3779b1 = ef1bf05d
m>>4=fef1bf05
m>>8=efef1bf0
m>>16=a4efef1b
m>>32=3c3ca4ef
m
≠0xef1bf05d
;它是 0x3c3ca4efef1bf05d
。
%x
仅处理 32 位值,而您处理的是 64 位值。对 64 位值使用 %lx
或 String(m, radix: 16)
:
let a: UInt = 0x6177206d, b: UInt = 0x9e3779b1
let m: UInt = a * b
print("""
let m = \(String(format:"%lx * %lx = %lx", a, b, m))
m>>4 = \(String(format:"%lx", m >> 4))
m>>8 = \(String(format:"%lx", m >> 8))
m>>16 = \(String(format:"%lx", m >> 16))
m>>32 = \(String(format:"%lx", m >> 32))
""")
或者如果你想看到它,请使用 %016lx
zero-padded(这样更容易看到正在发生的变化),产生:
let m = 000000006177206d * 000000009e3779b1 = 3c3ca4efef1bf05d
m>>4 = 03c3ca4efef1bf05
m>>8 = 003c3ca4efef1bf0
m>>16 = 00003c3ca4efef1b
m>>32 = 000000003c3ca4ef
为什么右移行为如下?
let a: UInt = 0x6177206d, b: UInt = 0x9e3779b1
let m: UInt = a * b
print("""
let m = \(String(format:"%x", a)) * \(String(format:"%x", b)) = \(String(format:"%x", m))
m>>4=\(String(format:"%x", m >> 4))
m>>8=\(String(format:"%x", m >> 8))
m>>16=\(String(format:"%x", m >> 16))
m>>32=\(String(format:"%x", m >> 32))
""")
生产:
let m = 6177206d * 9e3779b1 = ef1bf05d m>>4=fef1bf05 m>>8=efef1bf0 m>>16=a4efef1b m>>32=3c3ca4ef
m
≠0xef1bf05d
;它是 0x3c3ca4efef1bf05d
。
%x
仅处理 32 位值,而您处理的是 64 位值。对 64 位值使用 %lx
或 String(m, radix: 16)
:
let a: UInt = 0x6177206d, b: UInt = 0x9e3779b1
let m: UInt = a * b
print("""
let m = \(String(format:"%lx * %lx = %lx", a, b, m))
m>>4 = \(String(format:"%lx", m >> 4))
m>>8 = \(String(format:"%lx", m >> 8))
m>>16 = \(String(format:"%lx", m >> 16))
m>>32 = \(String(format:"%lx", m >> 32))
""")
或者如果你想看到它,请使用 %016lx
zero-padded(这样更容易看到正在发生的变化),产生:
let m = 000000006177206d * 000000009e3779b1 = 3c3ca4efef1bf05d m>>4 = 03c3ca4efef1bf05 m>>8 = 003c3ca4efef1bf0 m>>16 = 00003c3ca4efef1b m>>32 = 000000003c3ca4ef