2016-12-15 8 views
1

Это мой код для преобразования байтовых данных в float. Я пробовал все ответы, приведенные на этом сайте. Я получаю экспоненциальное значение для этого "< 44fa0000>" байтовых данныхКак преобразовать байты в значение float в swift?

static func returnFloatValue(mutableData:NSMutableData)->Float 
    { 
     let qtyRange = mutableData.subdataWithRange(NSMakeRange(0, 4)) 
     let qtyString = String(qtyRange) 
     let qtyTrimString = qtyString.stringByTrimmingCharactersInSet(NSCharacterSet(charactersInString: "<>")) 
     let qtyValue = Float(strtoul(qtyTrimString, nil, 16)/10) 
     return qtyValue 
    } 

Благодаря

+0

Какое значение вы ожидаете? –

+0

@MartinR a float value –

+0

'1.15723e + 09' (то, что вы называете« экспоненциальным значением ») * является * значением поплавка. Если это не то, что вы ожидаете, сообщите нам, каков должен быть результат и почему. В противном случае мы можем только догадываться. –

ответ

7

<44fa0000> является big-endian представление памяти двоичного числа с плавающей запятой 2000.0. Чтобы получить номер обратно от данных, вы должны сначала его прочитать в UInt32, конвертировать из big-endian в host byorder, а затем отличить результат от a Float.

В Swift 2, что было бы

func floatValueFromData(data: NSData) -> Float { 
    return unsafeBitCast(UInt32(bigEndian: UnsafePointer(data.bytes).memory), Float.self) 
} 

Пример:

let bytes: [UInt8] = [0x44, 0xFA, 0x00, 0x00] 
let data = NSData(bytes: bytes, length: 4) 

print(data) // <44fa0000> 
let f = floatValueFromData(data) 
print(f) // 2000.0 

В Swift 3 вы бы использовать Data вместо NSData, а unsafeBitCast может быть заменен Float(bitPattern:) Инициализатор:

func floatValue(data: Data) -> Float { 
    return Float(bitPattern: UInt32(bigEndian: data.withUnsafeBytes { $0.pointee })) 
} 
+0

Большое спасибо martin .. :) –

+0

@MartinR Можете ли вы добавить обратную сторону этого процесса, означает float to bytes, Это очень актуально. –

0

Используйте эту функцию:

static func returnFloatValue(data: NSMutableData) -> Float { 
    let bytes = [UInt8](data as Data) 
    var f: Float = 0 

    memcpy(&f, bytes, 4) 
    return f 
} 

И вы можете увидеть его в действии здесь:

var initialValue: Float = 19.200 

let data = NSMutableData(bytes: &initialValue, length: 4) 

func returnFloatValue(data: NSMutableData) -> Float { 
    let bytes = [UInt8](data as Data) 
    var f: Float = 0 

    memcpy(&f, bytes, 4) 
    return f 
} 

var result:Float = returnFloatValue(data: data) 

print("f=\(result)")// f=19.2 
+0

Я получаю эту ошибку Не могу отличить значение типа «Swift.Int» (0x111dbd1a0) до «Swift.UInt8» (0x111dbc858). –

+0

Какую быструю версию вы используете? – vladiulianbogdan