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)
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
.
FloatingPoint
rounded() methodIn 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
FloatingPoint
rounded(_:) methodlet 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
round
functionFoundation 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
Double
extension custom method built with Darwin round
and pow
functionsIf 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
NSDecimalNumber
rounding(accordingToBehavior:) methodIf 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
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
NSString
init(format:arguments:) initializerIf 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
String
init(format:_:) initializerSwift’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
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")
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
}
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
Not Swift but I'm sure you get the idea.
pow10np = pow(10,num_places);
val = round(val*pow10np) / pow10np;
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
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