1

How can one convert an array of bytes into a double value in Swift?

(It's an NSInputStream extension)

My snippet attached below, but it's not returning correct double value:

func readDouble() -> Double
{
var readBuffer = Array<UInt8>(count:sizeof(Double), repeatedValue: 0)

        let numberOfBytesRead = self.read(&readBuffer, maxLength: readBuffer.count)
        let help1 = Int(readBuffer[0] & 0xff) << 56 | Int(readBuffer[1] & 0xff) << 48
        let help2 = Int(readBuffer[2] & 0xff) << 40 | Int(readBuffer[3] & 0xff) << 32
        let help3 = Int(readBuffer[4] & 0xff) << 24 | Int(readBuffer[5] & 0xff) << 16
        let help4 = (Int(readBuffer[6] & 0xff) << 8) | Int(readBuffer[7] & 0xff)
        return Double(help1 | help2 | help3 | help4)
}
7
  • How is the data represented in the input stream? As an integer or IEEE binary double? Which byte order? What result do you get and what do you expect? Commented Aug 2, 2015 at 15:25
  • It's an array of doubles written in java. Commented Aug 2, 2015 at 15:26
  • You are asking the Swift people, so it might be helpful to add the information how Java writes an array of doubles. Commented Aug 2, 2015 at 15:27
  • What does println(readBuffer) show (after the read operation), and what should be the result? Commented Aug 2, 2015 at 15:32
  • Possible duplicate of Convert an Objective-C method into Swift for NSInputStream (convert bytes into double) ? Commented Aug 2, 2015 at 15:37

2 Answers 2

3

It's very simple:

extension FloatingPoint {

    init?(_ bytes: [UInt8]) {

        guard bytes.count == MemoryLayout<Self>.size else { return nil }

        self = bytes.withUnsafeBytes {

            return $0.load(fromByteOffset: 0, as: Self.self)
        }
    }
}

let array: [UInt8] =  [0, 0, 0, 0, 0, 0, 240, 63]
let num = Double(array) // 1.0

This code does work for any floating point type in Swift.

Swift 3.0 on macOS (little-endian representation of Double)

You can look up my cheat sheet for byte conversion here. (little/big endian number conversion)

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

2 Comments

I don't understand how is that byte array is converted into a Double. Currently running into issues when converting data
What is it that you don't understand? This is just a convenient initializer that re-interprets an array of UInt8 as the floating point type of your choice. It's your responsibility to provide the correct stream of bytes Swift would expect.
0

My understanding is that your byte array is a serialization of the binary representation. However, the Double constructor you're using takes an integer value and returns a corresponding Double. Double(3) returns 3.0.

The right constructor would probably be Double(_bits:), but it accepts a Builtin.FPIEEE64 and it looks like its availability is an implementation detail. You should probably consider making a C function and bridge it to Swift.

1 Comment

You can read from an input stream directly into a Swift Double variable, see for example stackoverflow.com/a/25846086/1187415. But it depends on the data representation (that's what I am still trying to figure out).

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.