四舍五入无穷大?

Rounding an Infinite Number?

此问题与较早的 有关,但我收到的是与除以 0 问题无关的无穷大。例如,下面的代码在控制台中打印 4.5300000000000002,但被标记为 .isInfinate,因此我无法使用 Codable 进行存储。如何从此示例中得出 4.53(作为双精度数)?

  //Calculation  
     func calculateMaximumAndAverageSkatingEfficiency() {

            let heartRateUnit:HKUnit = HKUnit(from: "count/min")
            let heartRatesAsDouble = heartRateValues.map { [=10=].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")
        }

    }

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

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

您的 round(to:) 方法不正确,因为它假定 "places" 是 十进制 数字。但是 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 绝不是 "infinite." 它略小于 5。我在您的代码中没有看到它应该生成无限值的任何地方。我会 double-check 你是如何确定的。