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

我有:

var totalWorkTimeInHours = (totalWorkTime/60/60)

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

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

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


当前回答

为了方便使用,我创建了一个扩展:

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

感谢其他答案的启发!

其他回答

基于Yogi的回答,这里有一个Swift函数来完成这项工作:

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

在Swift 5.5和Xcode 13.2中:

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

例子:

附注:自Swift 2.0和Xcode 7.2以来一直如此

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.

我会用

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

然后把。3f改成任何你需要的十进制数

我想知道是否有可能纠正用户的输入。也就是说,如果他们输入三个小数而不是两个小数来表示一美元的金额。比如说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


}