浮点数精度问题

由于计算机只能表示二进制整数和小数,因为并不是所有浮点数都能准确表示为二进制数,这些浮点数在计算机中的表示是不精确的。
我们判断两个浮点数A和B是否相等,并不能直接用==,而需要用abs(A - B) < FLT_EPSILON来判断,FLT_EPSILON是最小单精度浮点数。

问题描述:
近日做语音播报距离的时候遇到一个问题。需要先将以米作单位的距离d,分解为xx公里xx百x十米(个位数字直接舍掉),然后进行播报。例如:2017.123米,应该播报为2公里10米。但是实际播报的是2公里9米。

问题分析:
在使用函数操作的时候没有问题,但是使用扩展操作时,误差被放大了,导致精度偏差。

    func test() {
        let d: Double = 2017.123
        self.testDouble(floor(d / 10) / 100)
        _ = (floor(d / 10) / 100).ext_distanceDecompose()
    }
    func testDouble(_ d: Double) {
        let str = String(format: "%.3f", (d * 1000) / 1000)
        let distArr = str.components(separatedBy: ".")
        print("\(d) \(distArr)")
    }
    func ext_distanceDecompose() -> [String] {
        var distArray: [String] = []
        let distStr = String(format: "%.3f", floor(self * 1000) / 1000)
        let distArr = distStr.components(separatedBy: ".")
        var front: Int = Int(distArr[0])!
        var after: Int = Int(distArr.last!)!
        ...
        print("\(self) \(distArray)")
        return distArray
    }

输出的结果是:

2.01 ["2", "010"]
2.01 ["2", "9"]

修改后:

    func test() {
        let d: Double = 2017.123
        self.testDouble(floor(d / 10) / 100)
        _ = 2017.ext_distanceDecompose1()
    }
    func testDouble(_ d: Double) {
        let str = String(format: "%.3f", (d * 1000) / 1000)
        let distArr = str.components(separatedBy: ".")
        print("\(d) \(distArr)")
    }
    func ext_distanceDecompose1() -> [String] {
        var distArray: [String] = []
        let distStr = String(format: "%.3f", floor(self / 10) / 100)
        let distArr = distStr.components(separatedBy: ".")
        var front: Int = Int(distArr[0])!
        var after: Int = Int(distArr.last!)!
        print("\(self) \(distArray)")
        return distArray
    }

输出结果:

2.01 ["2", "010"]
2017.0 ["2", "10"]

参考:
http://blog.csdn.net/renwotao2009/article/details/51637163

猜你喜欢

转载自blog.csdn.net/dangyalingengjia/article/details/79425374