Get raw float bytes in Swift

How can I read raw Float or Double bytes in Swift?

Example:

 let x = Float(1.5) let bytes1: UInt32 = getRawBytes(x) let bytes2: UInt32 = 0b00111111110000000000000000000000 

I want bytes1 and bytes2 contain the same value, since this binary number is a representation of Float 1.5 .

I need it to perform bitwise operations such as & and >> (they are not defined in the float).

+5
source share
3 answers

Update for Swift 3: Starting with Swift 3, all floating point types have the bitPattern property, which returns an unsigned integer with the same memory representation and the corresponding init(bitPattern:) constructor for the opposite conversion.

Example: Float - UInt32 :

 let x = Float(1.5) let bytes1 = x.bitPattern print(String(format: "%#08x", bytes1)) // 0x3fc00000 

Example: UInt32 to Float :

 let bytes2 = UInt32(0x3fc00000) let y = Float(bitPattern: bytes2) print(y) // 1.5 

In the same way, you can convert between Double and UInt64 , or between CGFloat and UInt .


Old answer for Swift 1.2 and Swift 2: Swift floating point types have the _toBitPattern() method:

 let x = Float(1.5) let bytes1 = x._toBitPattern() print(String(format: "%#08x", bytes1)) // 0x3fc00000 let bytes2: UInt32 = 0b00111111110000000000000000000000 print(String(format: "%#08x", bytes2)) // 0x3fc00000 print(bytes1 == bytes2) // true 

This method is part of the FloatingPointType protocol to which Float , Double and CGFloat correspond to:

 /// A set of common requirements for Swift floating point types. protocol FloatingPointType : Strideable { typealias _BitsType static func _fromBitPattern(bits: _BitsType) -> Self func _toBitPattern() -> _BitsType // ... } 

(Starting with Swift 2, this definition is no longer displayed in the API, but they still exist and work as before.)

The actual _BitsType definition _BitsType not appear in the API documentation, but UInt32 for Float , UInt64 for Double and Int for CGFloat :

 print(Float(1.0)._toBitPattern().dynamicType) // Swift.UInt32 print(Double(1.0)._toBitPattern().dynamicType) // Swift.UInt64 print(CGFloat(1.0)._toBitPattern().dynamicType) // Swift.UInt 

_fromBitPattern() can be used to convert to another Direction:

 let y = Float._fromBitPattern(0x3fc00000) print(y) // 1.5 
+10
source

You can use unsafeBitCast , for example:

 let x = Float(1.5) let bytes1: UInt32 = unsafeBitCast(x, UInt32.self) let bytes2: UInt32 = 0b00111111110000000000000000000000 if (bytes1 == bytes2) { println ("Success") } 

The above excerpts are "Success" at startup.

+3
source

Failed to get this to work:

 let x = Float(1.5) let bytes1 = x.bitPattern print(String(format: "%#08x", bytes1)) // 0x3fc00000 

or that:

 let bytes1: UInt32 = unsafeBitCast(x, UInt32.self) 

So, I went for this:

 print(String(x.bitPattern, radix: 2)) 
0
source

All Articles