簡體   English   中英

Swift 將數據轉換為雙精度給我錯誤的值

[英]Swift Converting Data to double give me wrong value

我有一個包含字節列表的數據:[64、69、207、65、61、225、199、151] 十六進制字符串等於:4045cf413de1c797 我正在使用這個 function 獲取字節:var bytes:[UInt64] = data .map { UInt64(bitPattern: Int64($0)) } 數據是一種數據類型

當我將它轉換為雙精度值時,我得到了錯誤的值我嘗試了幾個 function 來轉換它:

示例 1:

 extension Data {
 enum Endianess {
    case little
    case big
}

func toFloat(endianess: Endianess = .little) -> Float? {
    guard self.count <= 4 else { return nil }

    switch endianess {
    case .big:
        let data = [UInt8](repeating: 0x00, count: 4-self.count) + self
        return data.withUnsafeBytes { $0.load(as: Float.self) }
    case .little:
        let data = self + [UInt8](repeating: 0x00, count: 4-self.count)
        return data.reversed().withUnsafeBytes { $0.load(as: Float.self) }
    }
    }
    }

這個給了我零

示例 2:

        var f:Float = 0.0
        memcpy(&f, bytes, 4)

結果:8.96831017167883e-44

示例 3:

       let floatNb:Float = dataSliced.reversed().withUnsafeBytes { $0.load(as: 
       Float.self) 
       }

結果:0.11024397

沒有 reversed() 我收到錯誤:致命錯誤:從未對齊的原始指針加載

示例 4:

  extension Numeric {
   init<D: DataProtocol>(_ data: D) {
    var value: Self = .zero
    let size = withUnsafeMutableBytes(of: &value, { data.copyBytes(to: $0)} )
    //assert(size == MemoryLayout.size(ofValue: value))
    self = value
  }
  }

結果是:-4.089067083288947e-194

好的結果是:43.61917851948163

我怎樣才能正確地將數據轉換為兩倍?

任何幫助將不勝感激

您的問題是您使用Float而不是Double作為目的地。 Float僅使用前 4 個字節。

let bytes = [UInt8](arrayLiteral: 64, 69, 207, 65, 61, 225, 199, 151)

let result = bytes.reversed().withUnsafeBytes {
    $0.load(
        as:Double.self
    )
}

assert(43.61917851948163 == result, "invalid result \(result)")

我終於通過像這樣分離 Int 和 Double 來解決這個問題: 對於 double:

   let bytes: [UInt16] = dataSliced.map { UInt16(bitPattern: Int16($0)) }
    dump(bytes)
    if(bytes.count == 8){
        var hexValue = dataSliced.toHex()
        hexValue = "0x\(hexValue)"
        let scanner = Scanner(string: hexValue)
        
        var decimalValue: UInt64 = 0
        scanner.scanHexInt64(&decimalValue)
        
        doubleValue = Double(bitPattern: decimalValue)
        print("doubleValue \(doubleValue)")

對於國際

    let decimalValue = dataSliced.reduce(0) { value, byte in
        return value << 8 | Int(byte)
    }
    return decimalValue

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM