How in swift to convert Int16 to two UInt8 Bytes
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)
Splitting a UInt16 to 2 UInt8 bytes and getting the hexa string of both. Swift
From your test cases, it seems like your values are 7 bits per byte.
You want 8192
to convert to 4000
.
You want 16383
to convert to 7F7F
.
Note that:
(0x7f << 7) + 0x7f == 16383
Given that:
let a = UInt8((int16 >> 7) & 0x7f)
let b = UInt8(int16 & 0x7f)
let result = String(format: "%02X%02X", a , b)
This gives:
"4000"
for 8128
"7F7F"
for 16383
To reverse the process:
let str = "7F7F"
let value = Int(str, radix: 16)!
let result = ((value >> 8) & 0x7f) << 7 + (value & 0x7f)
print(result) // 16383
How to convert UInt16 to UInt8 in Swift 3?
As the error message indicates, you have to use withMemoryRebound()
to reinterpret the pointer to UInt16
as a pointer to UInt8
:
let bytes = withUnsafePointer(to: &bigEndian) {
$0.withMemoryRebound(to: UInt8.self, capacity: MemoryLayout.size(ofValue: bigEndian)) {
Array(UnsafeBufferPointer(start: $0, count: MemoryLayout.size(ofValue: bigEndian)))
}
}
The closures are invoked with pointers ($0
) which are only valid
for the lifetime of the closure and must not be passed to the outside
for later use. That's why an Array
is created and used as return value.
There is a simpler solution however:
let bytes = withUnsafeBytes(of: &bigEndian) { Array($0) }
Explanation: withUnsafeBytes
invokes the closure with a UnsafeRawBufferPointer
to the storage of the bigEndian
variable.
Since UnsafeRawBufferPointer
is a Sequence
of UInt8
, an array
can be created from that with Array($0)
.
Convert a two byte UInt8 array to a UInt16 in Swift
If you want to go via NSData
then it would work like this:
let bytes:[UInt8] = [0x01, 0x02]
println("bytes: \(bytes)") // bytes: [1, 2]
let data = NSData(bytes: bytes, length: 2)
print("data: \(data)") // data: <0102>
var u16 : UInt16 = 0 ; data.getBytes(&u16)
// Or:
let u16 = UnsafePointer<UInt16>(data.bytes).memory
println("u16: \(u16)") // u16: 513
Alternatively:
let bytes:[UInt8] = [0x01, 0x02]
let u16 = UnsafePointer<UInt16>(bytes).memory
print("u16: \(u16)") // u16: 513
Both variants assume that the bytes are in the host byte order.
Update for Swift 3 (Xcode 8):
let bytes: [UInt8] = [0x01, 0x02]
let u16 = UnsafePointer(bytes).withMemoryRebound(to: UInt16.self, capacity: 1) {
$0.pointee
}
print("u16: \(u16)") // u16: 513
Convert Int to Array of UInt8 in swift
You could do it this way:
let x: Int = 2019
let length: Int = 2 * MemoryLayout<UInt8>.size //You could specify the desired length
let a = withUnsafeBytes(of: x) { bytes in
Array(bytes.prefix(length))
}
let result = Array(a.reversed()) //[7, 227]
Or more generally, we could use a modified version of this snippet:
func bytes<U: FixedWidthInteger,V: FixedWidthInteger>(
of value : U,
to type : V.Type,
droppingZeros: Bool
) -> [V]{
let sizeInput = MemoryLayout<U>.size
let sizeOutput = MemoryLayout<V>.size
precondition(sizeInput >= sizeOutput, "The input memory size should be greater than the output memory size")
var value = value
let a = withUnsafePointer(to: &value, {
$0.withMemoryRebound(
to: V.self,
capacity: sizeInput,
{
Array(UnsafeBufferPointer(start: $0, count: sizeInput/sizeOutput))
})
})
let lastNonZeroIndex =
(droppingZeros ? a.lastIndex { $0 != 0 } : a.indices.last) ?? a.startIndex
return Array(a[...lastNonZeroIndex].reversed())
}
let x: Int = 2019
bytes(of: x, to: UInt8.self, droppingZeros: true) // [7, 227]
bytes(of: x, to: UInt8.self, droppingZeros: false) // [0, 0, 0, 0, 0, 0, 7, 227]
Convert parts of [UInt8] into UInt8
Given an array :
let bytes: [UInt8] = [204, 74, 3, 0, 97, 168, 209, 239]
let's get the length of the message:
let length = Int(bytes[2])
msg
is the variable that will store the result:
var msg = 0
index
will point to the indexes of the octets of the whole message, from the LSB (higher index in bytes
), to the MSB (lower index in bytes
)
var index = bytes.count - 3
power
is the power with which we'll be shifting the octets
var power = 1
Then we calculate the message this way :
while index > 2 {
msg += Int(bytes[index]) * power
power = power << 8
index -= 1
}
The result is :
print(msg) //25000
Or as @JoshCaswell suggests :
var msg: UInt64 = 0
var index = 3
while index < bytes.count - 2 {
msg <<= 8 //msg = msg << 8
msg += UInt64(bytes[index])
index += 1
}
In both solutions, we suppose that the message can fit into an Int
or UInt64
Convert bytes/UInt8 array to Int in Swift
There are two problems:
Int
is a 64-bit integer on 64-bit platforms, your input data
has only 32-bit.Int
uses a little-endian representation on all current Swift platforms,
your input is big-endian.
That being said the following would work:
let array : [UInt8] = [0, 0, 0, 0x0E]
var value : UInt32 = 0
let data = NSData(bytes: array, length: 4)
data.getBytes(&value, length: 4)
value = UInt32(bigEndian: value)
print(value) // 14
Or using Data
in Swift 3:
let array : [UInt8] = [0, 0, 0, 0x0E]
let data = Data(bytes: array)
let value = UInt32(bigEndian: data.withUnsafeBytes { $0.pointee })
With some buffer pointer magic you can avoid the intermediate
copy to an NSData
object (Swift 2):
let array : [UInt8] = [0, 0, 0, 0x0E]
var value = array.withUnsafeBufferPointer({
UnsafePointer<UInt32>($0.baseAddress).memory
})
value = UInt32(bigEndian: value)
print(value) // 14
For a Swift 3 version of this approach, see ambientlight's answer.
How would I convert a [UInt8] to [UInt16] in Swift?
try something like:
var byteArr:[UInt8] = [126, 34, 119, 55, 1, 159, 144, 24, 108, 226, 49, 178, 60, 119, 133, 97, 189, 49, 111, 208]
var newArray:[UInt16] = byteArr.map { UInt16($0) }
map performs a function on each element of an array and returns a new array
Related Topics
How to Attach an Object to Your Camera Position with Arkit Swift
How to Record Video in Realitykit
How to Check for 'Nil' in While Loop Condition in Swift
Case Insensitive Dictionary in Swift
Is Removing a Notificationcenter Observer That Was Created with Closure Syntax by Name Adequate
Sliding One Swiftui View Out from Underneath Another
Convert Screen Coordinates to Metal's Normalized Device Coordinates
Understanding @Binding in Swiftui
How to Add "%" to Data in iOS-Chart
Swiftui MACos Nswindow Instance
Uialertcontroller Change Font Color
Swift Diffabledatasource Make Insert&Delete Instead of Reload
Proper Model for Multiple Alamofire Requests for Multiple Websites