在swift中将double值舍入到x个小数位数

任何人都可以告诉我如何在Swift中将double值舍入到x个小数位数?

我有:

var totalWorkTimeInHours = (totalWorkTime/60/60) 

totalWorkTime是NSTimeInterval(双)秒。

totalWorkTimeInHours将给我的时间,但它给了我这么长的精确数量,如1.543240952039 ……

当我打印totalWorkTimeInHours时,我怎样才能把它降低到1.543?

你可以使用Swift的round函数来完成这个任务。

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

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

除了任何types的printf(...)String(format: ...)解决scheme之外,此操作的结果仍然是Doubletypes的。

编辑:
关于有时不起作用的评论,请阅读:

计算机科学家应该知道什么是浮点运算

Swift 2的扩展

更通用的解决scheme是以下扩展,它适用于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被replace为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的示例四舍五入到小数点后四位:

 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 

使用带formatstring的String构造函数:

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

在Swift 2.0和Xcode 7.2中:

 let pi: Double = 3.14159265358979 String(format:"%.2f", pi) 

例:

在这里输入图像描述

使用Swift 3,根据您的需要,您可以select以下八种风格中的一种,以获得Double的舍入结果。


#1。 使用FloatingPoint rounded()方法

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

用法:

 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 rounded(_:)方法与FloatingPointRoundingRule.toNearestOrEven

用法:

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

#3。 使用达尔文round函数

基金会通过达尔文提供一个roundfunction。

用法:

 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 roundpow函数构build的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

如果需要, NSDecimalNumber提供了一个详细但function强大的四舍五入小数的解决scheme。

用法:

 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。 使用NSString init(format:arguments:)初始值设定项

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

用法:

 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 

#7。 String init(format:_:)初始化程序样式

Swift的Stringtypes与Foundation的NSString类桥接(可以通过阅读Swift编程语言了解更多信息)。 因此,您可以使用下面的代码为了从舍入操作返回一个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 

#8。 使用NumberFormatter

如果你接受一个String? 从你的四舍五入操作, NumberFormatter提供了一个高度可定制的解决scheme。

用法:

 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") 

基于瑜珈的回答,下面是一个可以完成这个工作的Swift函数:

 func roundToPlaces(value:Double, places:Int) -> Double { let divisor = pow(10.0, Double(places)) return round(value * divisor) / divisor } 

在Swift 3.0和Xcode 8.0中:

  extension Double { func roundTo(places: Int) -> Double { let divisor = pow(10.0, Double(places)) return (self * divisor).rounded() / divisor } } 

像这样使用这个扩展名,

 let doubleValue = 3.567 let roundedValue = doubleValue.roundTo(places: 2) print(roundedValue) // prints 3.56 

方便的方式可以是使用Doubletypes的扩展

 extension Double { var roundTo2f: Double {return Double(round(100 *self)/100) } var roundTo3f: Double {return Double(round(1000*self)/1000) } } 

用法:

 let regularPie: Double = 3.14159 var smallerPie: Double = regularPie.roundTo3f // results 3.142 var smallestPie: Double = regularPie.roundTo2f // results 3.14 

这是一个很长的解决方法,如果您的需求稍微复杂一点,这可能会派上用场。 您可以在Swift中使用数字格式化程序。

 let numberFormatter: NSNumberFormatter = { let nf = NSNumberFormatter() nf.numberStyle = .DecimalStyle nf.minimumFractionDigits = 0 nf.maximumFractionDigits = 1 return nf }() 

假设你想要打印的variables是

 var printVar = 3.567 

这将确保它以所需格式返回:

 numberFormatter.StringFromNumber(printVar) 

这里的结果将是“3.6”(四舍五入)。 虽然这不是最经济的解决scheme,但是我提供它是因为OP提到打印(在这种情况下string不是不可取的),并且因为这个类允许设置多个参数。

我会用

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

并将.3f更改为您需要的任意十进制数字

使用内置的基础达尔文库

SWIFT 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

不是斯威夫特,但我相信你明白了。

 pow10np = pow(10,num_places); val = round(val*pow10np) / pow10np; 

这是四舍五入到N个有效数字的更灵活的algorithm

Swift 3解决scheme

 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 

格式化双重属性的最佳方法是使用Apple预定义的方法。

 mutating func round(_ rule: FloatingPointRoundingRule) 

FloatingPointRoundingRule是一个具有以下可能性的枚举

查点个案:

case fromFromZero舍入到最接近的允许值,其值大于或等于源的值。

向下舍入舍入到最接近的小于或等于源的允许值。

case toNearestOrAwayFromZero舍入到最接近的允许值; 如果两个值相等,则select较大幅度的值。

case toNearestOrEven舍入到最接近的允许值; 如果两个值相等,则select偶数。

zeroero的情况舍入到最接近的允许值,其大小小于或等于源的值。

case up向上舍入到大于或等于源的最接近的允许值。

 var aNumber : Double = 5.2 aNumber.rounded(.up) // 6.0 

将double值舍入为x的十进制数
没有。 十进制后的数字

var x = 1.5657676754
var y =(x * 10000).rounded()/ 10000
print(y)// 1.5658


var x = 1.5657676754
var y =(x * 100).rounded()/ 100
print(y)// 1.57


var x = 1.5657676754
var y =(x * 10).round()/ 10
print(y)// 1.6

这是一行代码

Swift 3.2,Xcode 9.0 GM

 let doubleValue : Double = 123.32565254455 self.lblValue.text = String(format:"%.2f", doubleValue) print(self.lblValue.text) 

输出 – 123.32

我发现这个问题是否有可能纠正用户的input。 那就是如果他们input三位小数而不是两位一美元。 说1.111而不是1.11,你可以通过四舍五入来修复吗? 许多原因的答案是否定的! 随着钱超过0.001,最终会导致一个真正的支票簿的问题。

这是一个function来检查用户input的时间过后的值太多。 但是,这将允许1.,1.1和1.11。

假定已经检查了从String到Double的成功转换的值。

 //func need to be where transactionAmount.text is in scope func checkDoublesForOnlyTwoDecimalsOrLess()->Bool{ var theTransactionCharacterMinusThree: Character = "A" var theTransactionCharacterMinusTwo: Character = "A" var theTransactionCharacterMinusOne: Character = "A" var result = false var periodCharacter:Character = "." var myCopyString = transactionAmount.text! if myCopyString.containsString(".") { if( myCopyString.characters.count >= 3){ theTransactionCharacterMinusThree = myCopyString[myCopyString.endIndex.advancedBy(-3)] } if( myCopyString.characters.count >= 2){ theTransactionCharacterMinusTwo = myCopyString[myCopyString.endIndex.advancedBy(-2)] } if( myCopyString.characters.count > 1){ theTransactionCharacterMinusOne = myCopyString[myCopyString.endIndex.advancedBy(-1)] } if theTransactionCharacterMinusThree == periodCharacter { result = true } if theTransactionCharacterMinusTwo == periodCharacter { result = true } if theTransactionCharacterMinusOne == periodCharacter { result = true } }else { //if there is no period and it is a valid double it is good result = true } return result } 

问题陈述:

 double d=3.0; d/100= 0.0299999999 

我需要0.03

解:

 NSNumber *doubleNSNumber=[[NSNumber alloc] initWithDouble:d/100.0]; double roundedNumber=[doubleNSNumber doubleValue]; roundedNumber=0.03