How to Convert a Double into a Byte Array in Swift

How to convert a double into a byte array in swift?

typealias Byte = UInt8

func toByteArray(var value: T) -> [Byte] {
return withUnsafePointer(&value) {
Array(UnsafeBufferPointer(start: UnsafePointer($0), count: sizeof(T)))
}
}

toByteArray(1729.1729)
toByteArray(1729.1729 as Float)
toByteArray(1729)
toByteArray(-1729)

But the results are reversed from your expectations (because of endianness):

[234, 149, 178, 12, 177, 4, 155, 64]
[136, 37, 216, 68]
[193, 6, 0, 0, 0, 0, 0, 0]
[63, 249, 255, 255, 255, 255, 255, 255]

Added:

func fromByteArray(value: [Byte], _: T.Type) -> T {
return value.withUnsafeBufferPointer {
return UnsafePointer($0.baseAddress).memory
}
}

let a: Double = 1729.1729
let b = toByteArray(a) // -> [234, 149, 178, 12, 177, 4, 155, 64]
let c = fromByteArray(b, Double.self) // -> 1729.1729

For Xcode8/Swift3.0:

func toByteArray(_ value: T) -> [UInt8] {
var value = value
return withUnsafePointer(to: &value) {
$0.withMemoryRebound(to: UInt8.self, capacity: MemoryLayout.size) {
Array(UnsafeBufferPointer(start: $0, count: MemoryLayout.size))
}
}
}

func fromByteArray(_ value: [UInt8], _: T.Type) -> T {
return value.withUnsafeBufferPointer {
$0.baseAddress!.withMemoryRebound(to: T.self, capacity: 1) {
$0.pointee
}
}
}

For Xcode8.1/Swift3.0.1

func toByteArray(_ value: T) -> [UInt8] {
var value = value
return withUnsafeBytes(of: &value) { Array($0) }
}

func fromByteArray(_ value: [UInt8], _: T.Type) -> T {
return value.withUnsafeBytes {
$0.baseAddress!.load(as: T.self)
}
}

How to convert an ContiguousArray of Floats into a byte array in Swift?

You can use the withUnsafeBytes() method to get a buffer pointer to the underlying bytes of the array's contiguous storage, and directly initialize an [UInt8] array from that buffer pointer. Example:

let floatArray: [Float] = [1.0, 2.0]
// Works also with a ContiguousArray:
// let floatArray: ContiguousArray = [1.0, 2.0]

let byteArray = floatArray.withUnsafeBytes { Array($0) }
print(byteArray) // [0, 0, 128, 63, 0, 0, 0, 64]

Equivalently (based on Leo's suggestion):

let byteArray = floatArray.withUnsafeBytes(Array.init)

The byte array contains the binary representation of the floating point numbers in host byte order (which is little-endian on all current Apple platforms). A conversion to big-endian is possible, but not without an intermediate copy to an integer array:

let floatArray: ContiguousArray = [1.0, 2.0]
let intArray = floatArray.map { $0.bitPattern.bigEndian }
let byteArray = intArray.withUnsafeBytes(Array.init)
print(byteArray) // 63, 128, 0, 0, 64, 0, 0, 0]

Reverse conversion: A simple method would be

let floatArray2 = byteArray.withUnsafeBytes { Array($0.bindMemory(to: Float.self)) }
print(floatArray2) // [1.0, 2.0]

However, that requires that the element storage of the byte array is properly aligned for floating point numbers. If that is not guaranteed then you can do

var floatArray2 = [Float](repeating: 0.0, count: byteArray.count / MemoryLayout.stride)
_ = floatArray2.withUnsafeMutableBytes { byteArray.copyBytes(to: $0) }
print(floatArray2) // [1.0, 2.0]

How to convert Int to byte array of 4 bytes in Swift?

In Java an integer is always 32-bit, but in Swift it can be 32-bit or 64-bit, depending on the platform. Your code creates a byte array with the same size as that of the Int type, on a 64-bit platform that are 8 bytes.

If you want to restrict the conversion to 32-bit integers then use Int32 instead of Int, the result will then be an array of 4 bytes, independent of the platform.

An alternative conversion method is

let value: Int32 = -1333
let array = withUnsafeBytes(of: value.bigEndian, Array.init)
print(array) // [255, 255, 250, 203]

Or as a generic function for integer type of all sizes:

func byteArray(from value: T) -> [UInt8] where T: FixedWidthInteger {
withUnsafeBytes(of: value.bigEndian, Array.init)
}

Example:

print(byteArray(from: -1333))        // [255, 255, 255, 255, 255, 255, 250, 203]
print(byteArray(from: Int32(-1333))) // [255, 255, 250, 203]
print(byteArray(from: Int16(-1333))) // [250, 203]

How to convert a float value to byte array in swift?

Float to NSData:

var float1 : Float = 40.0
let data = NSData(bytes: &float1, length: sizeofValue(float1))
print(data) // <00002042>

... and back to Float:

var float2 : Float = 0
data.getBytes(&float2, length: sizeofValue(float2))
print(float2) // 40.0

(The same would work for other "simple" types like Double,
Int, ...)

Update for Swift 3, using the new Data type:

var float1 : Float = 40.0
let data = Data(buffer: UnsafeBufferPointer(start: &float1, count: 1))
print(data as NSData) // <00002042>

let float2 = data.withUnsafeBytes { $0.pointee } as Float
print(float2) // 40.0

(See also round trip Swift number types to/from Data)

Update for Swift 4 and later:

var float1 : Float = 40.0
let data = Data(buffer: UnsafeBufferPointer(start: &float1, count: 1))

let float2 = data.withUnsafeBytes { $0.load(as: Float.self) }
print(float2) // 40.0

Remark: load(as:) requires the data to be properly aligned, for Float that would be on a 4 byte boundary. See e.g. round trip Swift number types to/from Data for other solutions which work for arbitrarily aligned data.

How to convert bytes to swift array

I figured out how to do what I was trying to do...
In the end, I solved my own problem lol

all I needed to do was decode it with swiftyjson

thank you all for your answers

AF.request(exampleUrl).response { response in
if let data = response.data, let s = String(data: data, encoding: .utf8) {
let arr = JSON(data)
debugPrint(arr)
debugPrint(arr[0][0])
debugPrint(s)
}
}

output



Related Topics



Leave a reply



Submit