Skip to content

Instantly share code, notes, and snippets.

@matachi
Created November 12, 2018 09:23
Show Gist options
  • Save matachi/c29f970867bfc3f1f1fe7db50dc44b47 to your computer and use it in GitHub Desktop.
Save matachi/c29f970867bfc3f1f1fe7db50dc44b47 to your computer and use it in GitHub Desktop.
Encode a Float as a UInt8 byte array in Swift.
extension Float {
/**
Converts the float to an array of UInt8.
With this method, it is possible to encode a float as bytes and later
unpack the bytes to a float again. Note though that some of the precision
is lost in the conversion.
For instance, a conversion of 0.75 with the maxRange 1.0 results in the
array `[233, 255, 255, 0]`. To convert the array back to a float, do the
following calculation:
(223 / 256 + 255 / 256 / 256 + 255 / 256 / 256 / 256) * (1.0 * 2.0) - 1.0 ≈
0.8749999 * 2.0 - 1.0 ≈
0.7499999
A conversion of 23.1337 with the maxRange 100.0 results in the array
`[157, 156, 114, 0]`. Converting it back:
(157 / 256 + 156 / 256 / 256 + 114 / 256 / 256 / 256) * (100.0 * 2.0) - 100.0 ≈
23.133683
*/
func toUint8Array(maxRange: Float) -> [UInt8] {
let max = (UInt32(UInt16.max) + 1) * UInt32(UInt32(UInt8.max) + 1) - 1
let int = UInt32(((self / maxRange + 1.0) / 2.0 * Float(max)).rounded())
let a = int.quotientAndRemainder(dividingBy: UInt32(UInt16.max) + 1)
let b = a.remainder.quotientAndRemainder(dividingBy: UInt32(UInt8.max) + 1)
return [UInt8(a.quotient), UInt8(b.quotient), UInt8(b.remainder), 0]
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment