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

前端 未结 28 2534
日久生厌
日久生厌 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")
    
    0 讨论(0)
  • 2020-11-22 06:29

    Building on Yogi's answer, here's a Swift function that does the job:

    func roundToPlaces(value:Double, places:Int) -> Double {
        let divisor = pow(10.0, Double(places))
        return round(value * divisor) / divisor
    }
    
    0 讨论(0)
  • 2020-11-22 06:31

    In Swift 3.0 and Xcode 8.0:

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

    Use this extension like so:

    let doubleValue = 3.567
    let roundedValue = doubleValue.roundTo(places: 2)
    print(roundedValue) // prints 3.56
    
    0 讨论(0)
  • 2020-11-22 06:33

    Not Swift but I'm sure you get the idea.

    pow10np = pow(10,num_places);
    val = round(val*pow10np) / pow10np;
    
    0 讨论(0)
  • 2020-11-22 06:34

    The best way to format a double property is to use the Apple predefined methods.

    mutating func round(_ rule: FloatingPointRoundingRule)
    

    FloatingPointRoundingRule is a enum which has following possibilities

    Enumeration Cases:

    case awayFromZero Round to the closest allowed value whose magnitude is greater than or equal to that of the source.

    case down Round to the closest allowed value that is less than or equal to the source.

    case toNearestOrAwayFromZero Round to the closest allowed value; if two values are equally close, the one with greater magnitude is chosen.

    case toNearestOrEven Round to the closest allowed value; if two values are equally close, the even one is chosen.

    case towardZero Round to the closest allowed value whose magnitude is less than or equal to that of the source.

    case up Round to the closest allowed value that is greater than or equal to the source.

    var aNumber : Double = 5.2
    aNumber.rounded(.up) // 6.0
    
    0 讨论(0)
  • 2020-11-22 06:36

    In Swift 5.3 and Xcode 12:

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

    Example:

    PS.: It still the same since Swift 2.0 and Xcode 7.2
    0 讨论(0)
提交回复
热议问题