You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

iOS Swift/SwiftUI二进制计算器:浮点数与负数转二进制方案问询

解决Swift中浮点数(含负数)转二进制的问题

首先明确:整数二进制和浮点数二进制的表示逻辑完全不同,浮点数遵循IEEE 754标准,通过符号位、指数位、尾数位编码,不能直接套用整数的转换方法。以下是针对你的二进制计算器场景的具体实现方案:

一、实现浮点数与二进制的互转函数

针对Double类型(三角函数运算默认返回Double),可以通过内存操作获取其IEEE 754双精度二进制表示,同时支持反向转换:

// 将Double转换为IEEE 754双精度二进制字符串(64位)
func doubleToBinaryString(_ value: Double) -> String {
    var value = value
    let data = Data(bytes: &value, count: MemoryLayout<Double>.size)
    let bits = data.flatMap { byte in
        (0..<8).reversed().map { bit in
            (byte >> bit) & 1 == 1 ? "1" : "0"
        }
    }
    return bits.joined()
}

// 将IEEE 754双精度二进制字符串转回Double
func binaryStringToDouble(_ binaryString: String) -> Double? {
    guard binaryString.count == 64 else { return nil }
    let bytes = stride(from: 0, to: 64, by: 8).map { startIndex in
        let byteRange = binaryString.index(binaryString.startIndex, offsetBy: startIndex)..<binaryString.index(binaryString.startIndex, offsetBy: startIndex+8)
        return UInt8(String(binaryString[byteRange]), radix: 2)!
    }
    var value: Double = 0
    withUnsafeMutableBytes(of: &value) { buffer in
        bytes.enumerated().forEach { offset, byte in
            buffer[offset] = byte
        }
    }
    return value
}

如果需要单精度Float的转换,只需把Double替换为Float,MemoryLayout<Double>.size改为MemoryLayout<Float>.size,二进制长度限制为32位即可。

二、适配三角函数运算的代码逻辑

修改你现有代码中处理三角函数的分支,完成「二进制输入→十进制浮点数→计算→二进制输出」的流程:

let expression = "sin(101)*sin(101)" // 输入为二进制字符串101(对应十进制5)
let separator = "*"
let components = expression.components(separatedBy: separator)        
var newString = ""

for component in components {
    // 处理三角函数分支
    if component.contains("sin") || component.contains("cos") || component.contains("tan") ||
        component.contains("sinh") || component.contains("cosh") || component.contains("tanh") {
        // 用正则提取函数名和括号内的二进制输入
        let regex = try! NSRegularExpression(pattern: "(sin|cos|tan|sinh|cosh|tanh)\\((.*?)\\)")
        if let match = regex.firstMatch(in: component, range: NSRange(component.startIndex..., in: component)) {
            let funcName = String(component[Range(match.range(at: 1), in: component)!])
            let binaryInput = String(component[Range(match.range(at: 2), in: component)!])
            
            // 二进制转十进制整数,再转为Double用于计算
            guard let decimalInt = binaryStringToInt(binaryInput) else { continue }
            let decimalDouble = Double(decimalInt)
            
            // 执行三角函数计算
            var result: Double = 0
            switch funcName {
            case "sin": result = sin(decimalDouble) // 默认接收弧度参数,如需角度请用sin(decimalDouble * .pi / 180)
            case "cos": result = cos(decimalDouble)
            case "tan": result = tan(decimalDouble)
            case "sinh": result = sinh(decimalDouble)
            case "cosh": result = cosh(decimalDouble)
            case "tanh": result = tanh(decimalDouble)
            default: continue
            }
            
            // 将计算结果拼接到表达式中
            newString += "\(result) \(separator)"
        }
    } else {
        // 原有整数运算逻辑保持不变
        newString += "\(binaryStringToInt(component) ?? 0) \(separator)"
    }
}

newString.removeLast(separator.count)
if let finalValue = parser.parse(newString)?.value {
    // 将最终结果转为二进制展示
    let resultBinary = doubleToBinaryString(finalValue)
    print("十进制结果:\(finalValue)")
    print("二进制结果(IEEE 754双精度):\(resultBinary)")
}

三、关键细节说明

  1. 弧度/角度切换:Swift标准库的三角函数默认接收弧度参数,如果你的计算器需要按角度计算,需先将十进制值转为弧度:sin(decimalDouble * .pi / 180)
  2. 二进制展示优化:64位二进制串较长,可拆分展示符号位、指数位、尾数位,提升可读性:
    let fullBinary = doubleToBinaryString(finalValue)
    let signBit = fullBinary.prefix(1)
    let exponentBits = fullBinary.dropFirst().prefix(11)
    let mantissaBits = fullBinary.dropFirst(12)
    print("符号位:\(signBit),指数位:\(exponentBits),尾数位:\(mantissaBits)")
    
  3. 精度保障:上述转换是严格遵循IEEE 754标准的编码转换,不会丢失浮点数本身的精度(除非超出类型的数值范围)。

内容的提问来源于stack exchange,提问作者Muhammad Danish Qureshi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.10 22:05:34