3

The code which I am using for getting data in bytes, but I am not getting correct byte data for float value

let count = data.length / sizeof(UInt32)

// create array of appropriate length:
var array = [UInt32](count: count, repeatedValue: 0)

// copy bytes into array
data.getBytes(&array, length:count * sizeof(UInt32))

print(array)
4
  • 2
    What exactly is the input data and what the expected result? The title says "convert a float value to byte array" and your code does "NSData to UInt32 array", so your problem is not clear to me :) Commented Apr 23, 2016 at 15:22
  • Hi Thanks for the reply, if I am having float value, I want to convert that float value in bytes. so let me know what should I do for that? Commented Apr 23, 2016 at 15:27
  • Example please? Do you want the IEEE 754 representation or the integer.fraction representation in binary? Commented Apr 23, 2016 at 15:39
  • Suppose for e.g float value is 40.0 , I want this float value to be converted in NSData, and then the reverse case also nsdata to float. Commented Apr 23, 2016 at 15:47

2 Answers 2

7

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.

Sign up to request clarification or add additional context in comments.

5 Comments

Float(bitPattern: UInt32(bigEndian: data.withUnsafeBytes { $0.pointee } )) whats different in this data to float conversion as it's outputting different value actually I need reverse of this means Float to Data but above code in your answer is not converting as expected, please help
Note that the Swift 3 version shown here now generates a warning with Swift 5: Initialization of 'UnsafeBufferPointer<Self>' results in a dangling buffer pointer
@featherless: I get a different warning “'withUnsafeBytes' is deprecated” and I have updated the code. It should now compile without warnings.
Thanks for the update Martin. The new code does work + compile but it looks like it doesn't handle misaligned data. See github.com/jverkoey/BinaryCodable/pull/58/files for the fix I put in place based on swift-nio's number conversion implementation: github.com/apple/swift-nio/blob/…
@featherless: That is correct, load(as:) requires the data to be properly aligned. (See also forums.swift.org/t/built-in-unaligned-loads/19664 in the Swift Forum.) For arbitrarily aligned data I wrote something here stackoverflow.com/a/38024025/1187415, that is essentially the same approach as in your link.
6

Swift 5 Solution

From Float to [UInt8]

extension Float {
   var bytes: [UInt8] {
       withUnsafeBytes(of: self, Array.init)
   }
}

Usage:

let number: Float = 36.5
let bytes = number.bytes

From [UInt8] to Float

bytes.withUnsafeBytes {
    $0.load(fromByteOffset: 0, as: Float.self)
}

To convert to Data, simply cast the array of bytes to Data

let data = Data(bytes)

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.