Проблема в том, что вы пытаетесь преобразовать значения UInt32
с прямым порядком байтов в Float
просто путем "переинтерпретации" тех же битовых комбинаций, что и новое значение (для этого Float(bitPattern:)
), но это не так все как Float хранит свои данные. Типы данных Swift Float
и Double
являются реализациями 32- и 64-битных типов данных с плавающей запятой из IEEE 754 . Есть много онлайн-ресурсов, которые объясняют это, но TL; DR заключается в том, что они хранят числа таким же образом, как научная запись, с мантиссой, возведенной в степень экспоненты.
Я думаю, что часть ваших трудностей связана с попытками сделать слишком много одновременно. Разбейте его на мелкие кусочки. Напишите функцию, которая принимает ваши данные и разбивает их на компоненты 3 UInt32
. Затем напишите отдельную функцию, которая выполняет любое преобразование для этих компонентов, например, превращает их в числа с плавающей точкой. Вот грубый пример:
import Foundation
func createTestData(x: UInt32, y: UInt32, z: UInt32) -> Data {
return [x, y, z]
.map { UInt32(littleEndian: $0) }
.withUnsafeBufferPointer { Data(buffer: $0) }
}
func decode(data: Data) -> (x: UInt32, y: UInt32, z: UInt32) {
let values = data.withUnsafeBytes { bufferPointer in
bufferPointer
.bindMemory(to: UInt32.self)
.map { rawBitPattern in
return UInt32(littleEndian: rawBitPattern)
}
}
assert(values.count == 3)
return (x: values[0], y: values[1], z: values[2])
}
func transform(ints: (x: UInt32, y: UInt32, z: UInt32))
-> (x: Float, y: Float, z: Float) {
let transform: (UInt32) -> Float = { Float($0) / 1000 } // define whatever transformation you need
return (transform(ints.x), transform(ints.y), transform(ints.z))
}
let testData = createTestData(x: 123, y: 456, z: 789)
print(testData) // => 12 bytes
let decodedVector = decode(data: testData)
print(decodedVector) // => (x: 123, y: 456, z: 789)
let intsToFloats = transform(ints: decodedVector)
print(intsToFloats) // => (x: 0.123, y: 0.456, z: 0.789)