谁能告诉我如何在Swift中舍入一个双数值到x位小数点后数位?

我有:

var totalWorkTimeInHours = (totalWorkTime/60/60)

totalWorkTime是一个NSTimeInterval (double),单位为秒。

totalWorkTimeInHours会给我小时数,但它给我的时间量是如此长的精确数字,例如1.543240952039......

当我打印totalWorkTimeInHours时,我如何将其四舍五入到1.543 ?


当前回答

var n = 123.111222333
n = Double(Int(n * 10.0)) / 10.0

结果:n = 123.1

将10.0(小数点后1位)更改为100.0(小数点后2位)、1000.0(小数点后3位)中的任意一个,以此作为您想要的小数后的位数。

其他回答

当我打印totalWorkTimeInHours时,我如何将其四舍五入到1.543 ?

要将totalWorkTimeInHours四舍五入为3位数字以便打印,使用String构造函数,它接受一个格式字符串:

print(String(format: "%.3f", totalWorkTimeInHours))

Swift 2扩展

一个更通用的解决方案是以下扩展,适用于Swift 2和iOS 9:

extension Double {
    /// Rounds the double to decimal places value
    func roundToPlaces(places:Int) -> Double {
        let divisor = pow(10.0, Double(places))
        return round(self * divisor) / divisor
    }
}

Swift 3扩展

在Swift 3中,round被圆润取代:

extension Double {
    /// Rounds the double to decimal places value
    func rounded(toPlaces places:Int) -> Double {
        let divisor = pow(10.0, Double(places))
        return (self * divisor).rounded() / divisor
    }
}

返回Double四舍五入到小数点后4位的示例:

let x = Double(0.123456789).roundToPlaces(4)  // x becomes 0.1235 under Swift 2
let x = Double(0.123456789).rounded(toPlaces: 4)  // Swift 3 version

Lots of example are using maths, the problem is floats are approximations of real number, there is no way to express 0.1 (1/10) exactly as a float just as there is no exact way to express ⅓ exactly using decimal points, so you need to ask your self exactly what your are trying to achieve, if you just want to display them leave them as they are in code, trying to round them is going to justify give you less accurate result as you are throwing away precious, round ⅓ in decimal notation to 1 decimal place is not going to give you a number closer to ⅓, us NumberFormate to round it, if you have something like a viewModel class it can be used to return a string representation to your models numbers. NumberFormaters give you lots of control on how numbers are formatted and the number of decimal places you want.

你可以使用Swift的round函数来实现这一点。

要对Double进行3位精度的四舍五入,首先将其乘以1000,四舍五入,然后将四舍五入结果除以1000:

let x = 1.23556789
let y = Double(round(1000 * x) / 1000)
print(y) /// 1.236

与任何类型的printf(…)或String(format:…)解决方案不同,此操作的结果仍然是Double类型。

编辑: 关于它有时不能工作的评论,请阅读这篇:每个程序员都应该知道的关于浮点算术的事情

在Swift 5中,根据你的需要,你可以从以下9种风格中选择一种,以便从Double中获得四舍五入的结果。


# 1。使用FloatingPoint圆角()方法

在最简单的情况下,您可以使用Double rounted()方法。

let roundedValue1 = (0.6844 * 1000).rounded() / 1000
let roundedValue2 = (0.6849 * 1000).rounded() / 1000
print(roundedValue1) // returns 0.684
print(roundedValue2) // returns 0.685

# 2。使用FloatingPoint舍入(_:)方法

let roundedValue1 = (0.6844 * 1000).rounded(.toNearestOrEven) / 1000
let roundedValue2 = (0.6849 * 1000).rounded(.toNearestOrEven) / 1000
print(roundedValue1) // returns 0.684
print(roundedValue2) // returns 0.685

# 3。使用达尔文圆函数

Foundation通过Darwin提供了一个圆函数。

import Foundation

let roundedValue1 = round(0.6844 * 1000) / 1000
let roundedValue2 = round(0.6849 * 1000) / 1000
print(roundedValue1) // returns 0.684
print(roundedValue2) // returns 0.685

# 4。使用使用Darwin round和pow函数构建的Double扩展自定义方法

如果您想多次重复前面的操作,重构代码可能是一个好主意。

import Foundation

extension Double {
    func roundToDecimal(_ fractionDigits: Int) -> Double {
        let multiplier = pow(10, Double(fractionDigits))
        return Darwin.round(self * multiplier) / multiplier
    }
}

let roundedValue1 = 0.6844.roundToDecimal(3)
let roundedValue2 = 0.6849.roundToDecimal(3)
print(roundedValue1) // returns 0.684
print(roundedValue2) // returns 0.685

# 5。使用NSDecimalNumber舍入(accordingToBehavior:)方法

如果需要,NSDecimalNumber提供了一个详细但强大的十进制数字舍入解决方案。

import Foundation

let scale: Int16 = 3

let behavior = NSDecimalNumberHandler(roundingMode: .plain, scale: scale, raiseOnExactness: false, raiseOnOverflow: false, raiseOnUnderflow: false, raiseOnDivideByZero: true)

let roundedValue1 = NSDecimalNumber(value: 0.6844).rounding(accordingToBehavior: behavior)
let roundedValue2 = NSDecimalNumber(value: 0.6849).rounding(accordingToBehavior: behavior)

print(roundedValue1) // returns 0.684
print(roundedValue2) // returns 0.685

# 6。使用NSDecimalRound(_:_:_:_:)函数

import Foundation

let scale = 3

var value1 = Decimal(0.6844)
var value2 = Decimal(0.6849)

var roundedValue1 = Decimal()
var roundedValue2 = Decimal()

NSDecimalRound(&roundedValue1, &value1, scale, NSDecimalNumber.RoundingMode.plain)
NSDecimalRound(&roundedValue2, &value2, scale, NSDecimalNumber.RoundingMode.plain)

print(roundedValue1) // returns 0.684
print(roundedValue2) // returns 0.685

# 7。使用NSString初始化器init(format:arguments:)

如果你想从舍入操作中返回一个NSString,使用NSString初始化器是一个简单而有效的解决方案。

import Foundation

let roundedValue1 = NSString(format: "%.3f", 0.6844)
let roundedValue2 = NSString(format: "%.3f", 0.6849)
print(roundedValue1) // prints 0.684
print(roundedValue2) // prints 0.685

# 8。使用String init(format:_:)初始化器

Swift的String类型与Foundation的NSString类桥接。因此,你可以使用下面的代码来从舍入操作中返回一个String:

import Foundation

let roundedValue1 = String(format: "%.3f", 0.6844)
let roundedValue2 = String(format: "%.3f", 0.6849)
print(roundedValue1) // prints 0.684
print(roundedValue2) // prints 0.685

# 9。使用NumberFormatter

如果你期望得到一个字符串?从舍入操作中,NumberFormatter提供了高度可定制的解决方案。

import Foundation

let formatter = NumberFormatter()
formatter.numberStyle = NumberFormatter.Style.decimal
formatter.roundingMode = NumberFormatter.RoundingMode.halfUp
formatter.maximumFractionDigits = 3

let roundedValue1 = formatter.string(from: 0.6844)
let roundedValue2 = formatter.string(from: 0.6849)
print(String(describing: roundedValue1)) // prints Optional("0.684")
print(String(describing: roundedValue2)) // prints Optional("0.685")