How to convert double to byte array in swift?

I know how to do this in java (see here ), but I could not find a quick equivalent for java ByteBuffer and therefore its .putDouble (double value).

Basically, I'm looking for a function like this:
func doubleToByteArray(value: Double) -> [UInt8]? { . . . } doubleToByteArray(1729.1729) // should return [64, 155, 4, 177, 12, 178, 149, 234] 
+13
ios swift byte bytearray bytebuffer
Nov 16 '14 at 3:58
source share
6 answers
 typealias Byte = UInt8 func toByteArray<T>(var value: T) -> [Byte] { return withUnsafePointer(&value) { Array(UnsafeBufferPointer(start: UnsafePointer<Byte>($0), count: sizeof(T))) } } toByteArray(1729.1729) toByteArray(1729.1729 as Float) toByteArray(1729) toByteArray(-1729) 

But the results are canceled from your expectations (due to judgment):

 [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<T>(value: [Byte], _: T.Type) -> T { return value.withUnsafeBufferPointer { return UnsafePointer<T>($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<T>(_ value: T) -> [UInt8] { var value = value return withUnsafePointer(to: &value) { $0.withMemoryRebound(to: UInt8.self, capacity: MemoryLayout<T>.size) { Array(UnsafeBufferPointer(start: $0, count: MemoryLayout<T>.size)) } } } func fromByteArray<T>(_ 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<T>(_ value: T) -> [UInt8] { var value = value return withUnsafeBytes(of: &value) { Array($0) } } func fromByteArray<T>(_ value: [UInt8], _: T.Type) -> T { return value.withUnsafeBytes { $0.baseAddress!.load(as: T.self) } } 
+43
Nov 16 '14 at 5:25
source share

Well, it wasn’t easy, but here it is:

 func doubleToByteArray(value: Double) -> [UInt8] { let count = sizeof(Double) var doubles: [Double] = [value] let data = NSData(bytes: doubles, length: count) var result = [UInt8](count: count, repeatedValue: 0) data.getBytes(&result, length: count) return result } 

Use with caution.

+6
Nov 16 '14 at 5:26
source share

Here is my updated version of the original solution.

 /// input: array of bytes /// -> get pointer to byte array (UnsafeBufferPointer<[Byte]>) /// -> access its base address /// -> rebind memory to target type T (UnsafeMutablePointer<T>) /// -> extract and return the value of target type func binarytotype <T> (_ value: [Byte], _: T.Type) -> T { return value.withUnsafeBufferPointer { $0.baseAddress! .withMemoryRebound(to: T.self, capacity: 1) { $0.pointee } } } /// input type: value of type T /// -> get pointer to value of T /// -> rebind memory to the target type, which is a byte array /// -> create array with a buffer pointer initialized with the source pointer /// -> return the resulted array func typetobinary <T> (_ value: T) -> [Byte] { var mv : T = value let s : Int = MemoryLayout<T>.size return withUnsafePointer(to: &mv) { $0.withMemoryRebound(to: Byte.self, capacity: s) { Array(UnsafeBufferPointer(start: $0, count: s)) } } } 

PS: Remember to replace Byte with UInt8.

+3
Sep 01 '16 at 19:46
source share

Solution in quick 3:

 public func toByteArray<T>(_ value: T) -> [Byte] { let totalBytes = MemoryLayout<T>.size var value = value return withUnsafePointer(to: &value) { valuePtr in return valuePtr.withMemoryRebound(to: Byte.self, capacity: totalBytes) { reboundPtr in return Array(UnsafeBufferPointer(start: reboundPtr, count: totalBytes)) } } } 
+3
Oct 18 '16 at 14:26
source share

The method above works using Swift 2, but I found a much simpler and faster way to do this conversion and vice versa:

 func binarytotype <T> (value: [UInt8], _: T.Type) -> T { return value.withUnsafeBufferPointer { return UnsafePointer<T>($0.baseAddress).memory } } func typetobinary <T> (var value: T) -> [UInt8] { return withUnsafePointer(&value) { Array(UnsafeBufferPointer(start: UnsafePointer<UInt8>($0), count: sizeof(T))) } } let a: Double = 0.25 let b: [UInt8] = typetobinary(a) // -> [0, 0, 0, 0, 0, 0, 208, 63] let c = binarytotype(b, Double.self) // -> 0.25 

I tested it with Xcode 7.2 on the playground.

+1
Feb 02 '16 at 19:52
source share

Accepted answers are dangerous because MemoryLayout provides you with a static type size T !

To work around this problem, you must create your own protocol and request Self in it:

 protocol ByteConvertible {} extension ByteConvertible { func toBytes() -> [UInt8] { let capacity = MemoryLayout<Self>.size var mutableValue = self return withUnsafePointer(to: &mutableValue) { return $0.withMemoryRebound(to: UInt8.self, capacity: capacity) { return Array(UnsafeBufferPointer(start: $0, count: capacity)) } } } } 

I already mentioned that the accepted answers are dangerous, and here is an example:

 let num = UInt8(42) MemoryLayout.size(ofValue: num) //=> 1 byte as expected let any: Any = num MemoryLayout.size(ofValue: any) //=> 32 bytes which is what will happen in the generic functions from the all the answers 

Swift 3.0

+1
Oct 29 '16 at 16:35
source share



All Articles