I have some binary data that encodes a two byte value as a signed integer.
bytes[1] = 255 // 0xFF
bytes[2] = 251 // 0xF1
This is fairly easy - I can extract an Int16
value from these bytes with:
Int16(bytes[1]) << 8 | Int16(bytes[2])
This is where I'm running into issues. Most of my data spec called for UInt
and that is easy but I'm having trouble extracting the two bytes that make up an Int16
let nv : Int16 = -15
UInt8(nv >> 8) // fail
UInt8(nv) // fail
How would I extract the two bytes that make up an Int16
value
Updated for Swift 5, two things to pay attention: As [UInt8]is stored in a contiguous region of memory, there's no need to convert it to Data, pointer can access all bytes directly. Int's byte order is little endian currently on all Apple platform, but this is not garanteed on other platforms. say we want [0, 0, 0, 0x0e]to convert to 14.
It turns out that Swift thinks that it is positive! Now the only difference between Int8 and Int16 is that the former is made up of a single byte, and the latter is made up of two bytes. Since it is made up of 2 bytes, an Int16 contains the range -32768 to 32767.
A variable can be declared as String type by following the below syntax, Swift provides the function of integer initializers using which we can convert a string into an Int type. To handle non-numeric strings, we can use nil coalescing using which the integer initializer returns an optional integer.
The ToInt16 method converts the bytes from index startIndex to startIndex + 1 to an Int16 value. The order of bytes in the array must reflect the endianness of the computer system's architecture; for more information, see the Remarks section of the BitConverter class topic.
You should work with unsigned integers:
let bytes: [UInt8] = [255, 251]
let uInt16Value = UInt16(bytes[0]) << 8 | UInt16(bytes[1])
let uInt8Value0 = uInt16Value >> 8
let uInt8Value1 = UInt8(uInt16Value & 0x00ff)
If you want to convert UInt16 to bit equivalent Int16 then you can do it with specific initializer:
let int16Value: Int16 = -15
let uInt16Value = UInt16(bitPattern: int16Value)
And vice versa:
let uInt16Value: UInt16 = 65000
let int16Value = Int16(bitPattern: uInt16Value)
In your case:
let nv: Int16 = -15
let uNv = UInt16(bitPattern: nv)
UInt8(uNv >> 8)
UInt8(uNv & 0x00ff)
You could use init(truncatingBitPattern: Int16)
initializer:
let nv: Int16 = -15
UInt8(truncatingBitPattern: nv >> 8) // -> 255
UInt8(truncatingBitPattern: nv) // -> 241
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With