Rounding a double value to x number of decimal places in swift
有人能告诉我如何用swift将一个双精度的值四舍五入到小数位数X吗?
我有:
1 | var totalWorkTimeInHours = (totalWorkTime/60/60) |
其中
当我打印
Swift 2的扩展
更通用的解决方案是以下扩展,它与Swift 2和iOS 9一起工作:
1 2 3 4 5 6 7 | 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 } } |
< BR>
SWIFT 3扩展在Swift 3中,
1 2 3 4 5 6 7 | 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 } } |
< BR>返回四舍五入到四位小数的示例:
1 2 | 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 |
您可以使用Swift的
要用3位精度对
1 2 3 | let x = 1.23556789 let y = Double(round(1000*x)/1000) print(y) // 1.236 |
除了任何类型的
编辑:关于有时不起作用的评论,请阅读:
每一个计算机科学家都应该知道什么是浮点运算
How do I round this down to, say, 1.543 when I print
totalWorkTimeInHours ?
要将
1 | print(String(format:"%.3f", totalWorkTimeInHours)) |
使用Swift 5,根据您的需要,您可以选择以下9种样式中的一种,以便从
在最简单的情况下,您可以使用
1 2 3 4 | 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。使用
1 2 3 4 | 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。使用达尔文
基金会通过达尔文提供了一个EDCOX1×3函数。
1 2 3 4 5 6 | 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。使用由达尔文
如果您想多次重复前面的操作,重构代码是一个好主意。
1 2 3 4 5 6 7 8 9 10 11 12 13 | 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。使用
如果需要,
1 2 3 4 5 6 7 8 9 10 11 | 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。使用
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | 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。使用
如果要从舍入操作返回
1 2 3 4 5 6 | 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。使用
SWIFT的EDOCX1×1类型是用基金会的EDCOX1×26类桥接的。因此,可以使用以下代码从舍入操作返回
1 2 3 4 5 6 | 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。使用
如果您希望从舍入操作中获得一个
1 2 3 4 5 6 7 8 9 10 11 | 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 2.0和Xcode 7.2中:
1 2 | let pi: Double = 3.14159265358979 String(format:"%.2f", pi) |
例子:
基于Yogi的答案,这里有一个快速的功能来完成这项工作:
1 2 3 4 | func roundToPlaces(value:Double, places:Int) -> Double { let divisor = pow(10.0, Double(places)) return round(value * divisor) / divisor } |
这是完全有效的代码
swift 3.0/4.0,xcode 9.0 gm/9.2
1 2 3 | let doubleValue : Double = 123.32565254455 self.lblValue.text = String(format:"%.f", doubleValue) print(self.lblValue.text) |
输出- 123
1 2 | self.lblValue_1.text = String(format:"%.1f", doubleValue) print(self.lblValue_1.text) |
输出- 123.3
1 2 | self.lblValue_2.text = String(format:"%.2f", doubleValue) print(self.lblValue_2.text) |
输出- 123.33
1 2 | self.lblValue_3.text = String(format:"%.3f", doubleValue) print(self.lblValue_3.text) |
输出-123.326
小数后特定数字的代码为:
1 2 | var a = 1.543240952039 var roundedString = String(format:"%.3f", a) |
这里,%.3f告诉Swift将这个数字四舍五入到小数点后3位。如果要双位数,可以使用此代码:
// String to Double
在Swift 3.0和Xcode 8.0中:
1 2 3 4 5 6 | extension Double { func roundTo(places: Int) -> Double { let divisor = pow(10.0, Double(places)) return (self * divisor).rounded() / divisor } } |
像这样使用这个扩展名,
1 2 3 | let doubleValue = 3.567 let roundedValue = doubleValue.roundTo(places: 2) print(roundedValue) // prints 3.56 |
Swift 4,xcode 10
1 | yourLabel.text = String(format:"%.2f", yourDecimalValue) |
一个方便的方法是使用double类型的扩展
1 2 3 4 | extension Double { var roundTo2f: Double {return Double(round(100 *self)/100) } var roundTo3f: Double {return Double(round(1000*self)/1000) } } |
用途:
1 2 3 | let regularPie: Double = 3.14159 var smallerPie: Double = regularPie.roundTo3f // results 3.142 var smallestPie: Double = regularPie.roundTo2f // results 3.14 |
使用内置的基础达尔文库
斯威夫特3
1 2 3 4 5 6 7 8 | extension Double { func round(to places: Int) -> Double { let divisor = pow(10.0, Double(places)) return Darwin.round(self * divisor) / divisor } } |
用途:
1 2 | let number:Double = 12.987654321 print(number.round(to: 3)) |
输出:12.988
这是一种很长的解决方法,如果您的需求稍微复杂一点,它可能会派上用场。您可以使用swift中的数字格式化程序。
1 2 3 4 5 6 7 | let numberFormatter: NSNumberFormatter = { let nf = NSNumberFormatter() nf.numberStyle = .DecimalStyle nf.minimumFractionDigits = 0 nf.maximumFractionDigits = 1 return nf }() |
假设要打印的变量是
1 | var printVar = 3.567 |
这将确保以所需格式返回:
1 | numberFormatter.StringFromNumber(printVar) |
因此,这里的结果将是"3.6"(四舍五入)。虽然这不是最经济的解决方案,但我给出它是因为上面提到的打印(在这种情况下,字符串不是不可取的),并且因为这个类允许设置多个参数。
我会用
1 | print(String(format:"%.3f", totalWorkTimeInHours)) |
把.3f改成你需要的十进制数。
格式化Double属性的最佳方法是使用Apple预定义的方法。
1 | mutating func round(_ rule: FloatingPointRoundingRule) |
floatingPointRoundingRule是一个枚举,具有以下可能性
枚举事例:
案例AwayFromZero四舍五入到最接近的允许值,该值的大小大于或等于源的大小。
病案下来四舍五入到小于或等于源的最近允许值。
从零开始存储案例色调四舍五入到最接近的允许值;如果两个值相等,则选择幅度较大的值。
储存箱色调四舍五入到最接近的允许值;如果两个值相等,则选择偶数。
零度情况四舍五入到最接近的允许值,该值的大小小于或等于源的大小。
案例四舍五入到最接近的允许值,该值大于或等于源。
1 2 | var aNumber : Double = 5.2 aNumber.rounded(.up) // 6.0 |
如果要对
所以你可以这样做:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | extension Double { /// Convert `Double` to `Decimal`, rounding it to `scale` decimal places. /// /// - Parameters: /// - scale: How many decimal places to round to. Defaults to `0`. /// - mode: The preferred rounding mode. Defaults to `.plain`. /// - Returns: The rounded `Decimal` value. func roundedDecimal(to scale: Int = 0, mode: NSDecimalNumber.RoundingMode = .plain) -> Decimal { var decimalValue = Decimal(self) var result = Decimal() NSDecimalRound(&result, &decimalValue, scale, mode) return result } } |
然后,您可以得到近似的
1 2 | let foo = 427.3000000002 let value = foo.roundedDecimal(to: 2) // results in 427.30 |
如果要用指定的小数位数(以及用户当前区域设置的字符串本地化)显示它,可以使用
1 2 3 4 5 6 7 | let formatter = NumberFormatter() formatter.maximumFractionDigits = 2 formatter.minimumFractionDigits = 2 if let string = formatter.string(for: value) { print(string) } |
要么:
使用
用
%.3f 格式说明符将Double 打字到String ,然后返回Double 。1Double(String(format:"%.3f", 10.123546789))!或扩展
Double 处理N位小数:1
2
3
4
5extension Double {
func rounded(toDecimalPlaces n: Int) -> Double {
return Double(String(format:"%.\(n)f", self))!
}
}
通过计算
乘以10^3,四舍五入,然后除以10^3…
1(1000 * 10.123546789).rounded()/1000或扩展
Double 处理N位小数:1
2
3
4
5
6extension Double {
func rounded(toDecimalPlaces n: Int) -> Double {
let multiplier = pow(10, Double(n))
return (multiplier * self).rounded()/multiplier
}
}
这是一种更为灵活的算法,可以四舍五入到n个有效数字
Swift 3解决方案
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | 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 |
不是很快,但我相信你会明白的。
1 2 | pow10np = pow(10,num_places); val = round(val*pow10np) / pow10np; |
将一个双精度值四舍五入到小数位数X小数后位数
1 2 3 | var x = 1.5657676754 var y = (x*10000).rounded()/10000 print(y) // 1.5658 |
1 2 3 | var x = 1.5657676754 var y = (x*100).rounded()/100 print(y) // 1.57 |
1 2 3 | var x = 1.5657676754 var y = (x*10).rounded()/10 print(y) // 1.6 |
我发现这个问题是想知道是否可以纠正用户的输入。也就是说,如果他们输入三位小数,而不是两位,则表示一美元金额。比如说1.111而不是1.11,你能通过四舍五入来修正它吗?有很多原因的答案是否定的!如果有了钱,任何超过0.001的东西最终都会在真正的支票簿中造成问题。
下面是一个函数,用于检查用户输入的值在该时间段之后是否过多。但允许1、1.1和1.11。
假定已检查该值是否已成功从字符串转换为double。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 | //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 } |
1 2 3 4 5 6 7 | //find the distance between two points let coordinateSource = CLLocation(latitude: 30.7717625, longitude:76.5741449 ) let coordinateDestination = CLLocation(latitude: 29.9810859, longitude: 76.5663599) let distanceInMeters = coordinateSource.distance(from: coordinateDestination) let valueInKms = distanceInMeters/1000 let preciseValueUptoThreeDigit = Double(round(1000*valueInKms)/1000) self.lblTotalDistance.text ="Distance is : \(preciseValueUptoThreeDigit) kms" |
您可以添加此扩展名:
1 2 3 4 5 | extension Double { var clean: String { return self.truncatingRemainder(dividingBy: 1) == 0 ? String(format:"%.0f", self) : String(format:"%.2f", self) } } |
这样称呼它:
1 2 | let ex: Double = 10.123546789 print(ex.clean) // 10.12 |
1 2 3 4 | extension String{ var roundedValue:String { return String(format:"%.3f", self) }} |
用途:
1 | totalWorkTimeInHours.roundedValue |