谁能告诉我如何在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 ?
当前回答
我想知道是否有可能纠正用户的输入。也就是说,如果他们输入三个小数而不是两个小数来表示一美元的金额。比如说1.111而不是1.11,你能通过四舍五入来修复它吗?出于很多原因,答案是否定的!对于金钱,任何超过0.001的东西最终都会在真正的支票簿上产生问题。
下面是一个函数,用于检查用户输入的句点之后是否有太多值。但是它允许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
}
其他回答
我想知道是否有可能纠正用户的输入。也就是说,如果他们输入三个小数而不是两个小数来表示一美元的金额。比如说1.111而不是1.11,你能通过四舍五入来修复它吗?出于很多原因,答案是否定的!对于金钱,任何超过0.001的东西最终都会在真正的支票簿上产生问题。
下面是一个函数,用于检查用户输入的句点之后是否有太多值。但是它允许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
}
在Swift 5.5和Xcode 13.2中:
let pi: Double = 3.14159265358979
String(format:"%.2f", pi)
例子:
附注:自Swift 2.0和Xcode 7.2以来一直如此
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
对于许多应用程序,需要精确的小数位数来舍入。
对于其他一些,您没有这样的限制,并希望“压缩”输出大小,但仍然希望避免将数字转换为字符串(反之亦然),就像导出具有数百万个数字的JSON一样。
在这种情况下,你可以使用'trick'来四舍五入显数(尾数),而不是整数。在这种情况下,你会得到最后的小数点 大多数数字仍然最多保留3位小数点后(如果需要的话),而有些数字会稍微多一些。
这是你在使用十进制数时所期望的结果:
5.2472 5.2516 5.2556 5.26 5.264
而不是:
5.24731462499949 5.251488374999099 5.25566283399894 5.259839374999501 5.264012208999702
let value = 5.24731462499949
print(value)
// 5.24731462499949
let valueSignificandRounded = round((1000 * 10) * value.significand) / (1000 * 10)
let valueRounded = CGFloat(sign: v.sign, exponent: v.exponent, significand: valueSignificandRounded)
print(valueRounded)
// 5.2472
为了方便使用,我创建了一个扩展:
extension Double {
var threeDigits: Double {
return (self * 1000).rounded(.toNearestOrEven) / 1000
}
var twoDigits: Double {
return (self * 100).rounded(.toNearestOrEven) / 100
}
var oneDigit: Double {
return (self * 10).rounded(.toNearestOrEven) / 10
}
}
var myDouble = 0.12345
print(myDouble.threeDigits)
print(myDouble.twoDigits)
print(myDouble.oneDigit)
打印结果如下:
0.123
0.12
0.1
感谢其他答案的启发!