谁能告诉我如何在Swift中舍入一个双数值到x位小数点后数位?
我有:
var totalWorkTimeInHours = (totalWorkTime/60/60)
totalWorkTime是一个NSTimeInterval (double),单位为秒。
totalWorkTimeInHours会给我小时数,但它给我的时间量是如此长的精确数字,例如1.543240952039......
当我打印totalWorkTimeInHours时,我如何将其四舍五入到1.543 ?
谁能告诉我如何在Swift中舍入一个双数值到x位小数点后数位?
我有:
var totalWorkTimeInHours = (totalWorkTime/60/60)
totalWorkTime是一个NSTimeInterval (double),单位为秒。
totalWorkTimeInHours会给我小时数,但它给我的时间量是如此长的精确数字,例如1.543240952039......
当我打印totalWorkTimeInHours时,我如何将其四舍五入到1.543 ?
当前回答
使用内置的达尔文基金会图书馆
斯威夫特3
extension Double {
func round(to places: Int) -> Double {
let divisor = pow(10.0, Double(places))
return Darwin.round(self * divisor) / divisor
}
}
用法:
let number:Double = 12.987654321
print(number.round(to: 3))
输出:12.988
其他回答
这是一个更灵活的算法舍入到N位有效数字
Swift 3解决方案
extension Double {
// Rounds the double to 'places' significant digits
func roundTo(places:Int) -> Double {
guard self != 0.0 else {
return 0
}
let divisor = pow(10.0, Double(places) - ceil(log10(fabs(self))))
return (self * divisor).rounded() / divisor
}
}
// Double(0.123456789).roundTo(places: 2) = 0.12
// Double(1.23456789).roundTo(places: 2) = 1.2
// Double(1234.56789).roundTo(places: 2) = 1200
在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")
不是斯威夫特,但我相信你明白我的意思。
pow10np = pow(10,num_places);
val = round(val*pow10np) / pow10np;
这是一种长期的变通方法,如果您的需求稍微复杂一点,它可能会派上用场。你可以在Swift中使用数字格式化器。
let numberFormatter: NSNumberFormatter = {
let nf = NSNumberFormatter()
nf.numberStyle = .DecimalStyle
nf.minimumFractionDigits = 0
nf.maximumFractionDigits = 1
return nf
}()
假设你想打印的变量是
var printVar = 3.567
这将确保它以所需的格式返回:
numberFormatter.StringFromNumber(printVar)
因此,这里的结果是“3.6”(四舍五入)。虽然这不是最经济的解决方案,但我这样做是因为OP提到了打印(在这种情况下String不是不可取的),并且因为该类允许设置多个参数。
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.