Rounding a double value to x number of decimal places in swift

前端 未结 28 2548
日久生厌
日久生厌 2020-11-22 06:11

Can anyone tell me how to round a double value to x number of decimal places in Swift?

I have:

var totalWorkTimeInHours = (totalWorkTime/60/60)
         


        
28条回答
  •  长情又很酷
    2020-11-22 06:29

    With Swift 5, according to your needs, you can choose one of the 9 following styles in order to have a rounded result from a Double.


    #1. Using FloatingPoint rounded() method

    In the simplest case, you may use the Double rounded() method.

    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. Using FloatingPoint rounded(_:) method

    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. Using Darwin round function

    Foundation offers a round function via 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. Using a Double extension custom method built with Darwin round and pow functions

    If you want to repeat the previous operation many times, refactoring your code can be a good idea.

    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. Using NSDecimalNumber rounding(accordingToBehavior:) method

    If needed, NSDecimalNumber offers a verbose but powerful solution for rounding decimal numbers.

    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. Using NSDecimalRound(_:_:_:_:) function

    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. Using NSString init(format:arguments:) initializer

    If you want to return a NSString from your rounding operation, using NSString initializer is a simple but efficient solution.

    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. Using String init(format:_:) initializer

    Swift’s String type is bridged with Foundation’s NSString class. Therefore, you can use the following code in order to return a String from your rounding operation:

    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. Using NumberFormatter

    If you expect to get a String? from your rounding operation, NumberFormatter offers a highly customizable solution.

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

提交回复
热议问题