如何在swift中将Int16转换为两个UInt8字节

Jee*_*eef 13 bit-manipulation swift

我有一些二进制数据,将两个字节的值编码为有符号整数.

bytes[1] = 255  // 0xFF
bytes[2] = 251  // 0xF1
Run Code Online (Sandbox Code Playgroud)

解码

这很容易 - 我可以Int16从这些字节中提取一个值:

Int16(bytes[1]) << 8 | Int16(bytes[2])
Run Code Online (Sandbox Code Playgroud)

编码

这是我遇到问题的地方.我的大多数数据规范要求UInt,这很容易,但我无法提取组成的两个字节Int16

let nv : Int16 = -15
UInt8(nv >> 8) // fail
UInt8(nv)      // fail
Run Code Online (Sandbox Code Playgroud)

我如何提取构成Int16值的两个字节

mix*_*xel 21

您应该使用无符号整数:

let bytes: [UInt8] = [255, 251]
let uInt16Value = UInt16(bytes[0]) << 8 | UInt16(bytes[1])
let uInt8Value0 = uInt16Value >> 8
let uInt8Value1 = UInt8(uInt16Value & 0x00ff)
Run Code Online (Sandbox Code Playgroud)

如果您想将UInt16转换为等效的Int16,那么您可以使用特定的初始化程序:

let int16Value: Int16 = -15
let uInt16Value = UInt16(bitPattern: int16Value)
Run Code Online (Sandbox Code Playgroud)

反之亦然:

let uInt16Value: UInt16 = 65000
let int16Value = Int16(bitPattern: uInt16Value)
Run Code Online (Sandbox Code Playgroud)

在你的情况下:

let nv: Int16 = -15
let uNv = UInt16(bitPattern: nv)

UInt8(uNv >> 8)
UInt8(uNv & 0x00ff)
Run Code Online (Sandbox Code Playgroud)


rin*_*aro 7

你可以使用init(truncatingBitPattern: Int16)初始化程序:

let nv: Int16 = -15
UInt8(truncatingBitPattern: nv >> 8) // -> 255
UInt8(truncatingBitPattern: nv) // -> 241
Run Code Online (Sandbox Code Playgroud)

  • Swift 4上的UInt8(truncatingIfNeeded:nv) (2认同)