舍入无限数?

时间:2018-02-23 20:48:16

标签: ios swift foundation infinite

这个问题与之前的question有关,但是我收到的无限数与除以0的问题无关。例如,下面的代码在控制台中打印4.5300000000000002但标记为.isInfinate,因此我无法使用Codable进行存储。如何从这个例子中导出4.53(作为双精度)?

  //Calculation  
     func calculateMaximumAndAverageSkatingEfficiency() {

            let heartRateUnit:HKUnit = HKUnit(from: "count/min")
            let heartRatesAsDouble = heartRateValues.map { $0.quantity.doubleValue(for: heartRateUnit)}
            let maxHeartRate = heartRatesAsDouble.max()
            guard let maxHeartRateUnwrapped = maxHeartRate else { return }

            maximumEfficiencyFactor = ((1760.0 * (maxSpeed / 60)) / maxHeartRateUnwrapped).round(to: 2)

            guard let averageIceTimeHeartRateUnwrapped = averageIceTimeHeartRate else { return }

            averageEfficiencyFactor = ((1760.0 * (averageSpeed / 60)) / averageIceTimeHeartRateUnwrapped).round(to: 2)

        }

    //Round extension I am using
    extension Double {

        func round(to places: Int) -> Double {
            let divisor = pow(10.0, Double(places))
            return Darwin.round(self * divisor) / divisor
        }

    }

//Usage 
  if let averageEfficiencyFactorUnwrapped = averageEfficiencyFactor {
        if averageEfficiencyFactorUnwrapped.isFinite {
            hockeyTrackerMetadata.averageEfficiencyFactor = averageEfficiencyFactorUnwrapped.round(to: 2)
        } else {
            print("AEF is infinite")
        }

    }

1 个答案:

答案 0 :(得分:4)

Double无法精确存储4.53,原因与您无法精确记下十进制值的1/3相同。 (如果您不清楚,请参阅What Every Programming Should Know About Floating-Point Arithmetic。)

如果您希望舍入为十进制而不是二进制,则需要使用十进制类型。请参阅Decimal

您的round(to:)方法不正确,因为它假设"地点"是十进制位数。但是Double以二进制数字工作。我相信你想要的是这个:

extension Double {
    func round(toDecimalPlaces places: Int) -> Decimal {
        var decimalValue = Decimal(self)
        var result = decimalValue
        NSDecimalRound(&result, &decimalValue, places, .plain)
        return result
    }
}

请注意,4.53绝不是"无限的。"它有点小于5.我在代码中的任何地方都看不到它应该产生无限的值。我会仔细检查你是如何确定的。