Home > Software design >  How to prevent currency with decimal rounds in Swift
How to prevent currency with decimal rounds in Swift

Time:01-19

Seems to be trivial but I couldn't figure out how to prevent the currency value from Rounding in Swift.

Below is my code:

let halfYearlyPrice = 71.99
var perMonthPrice = (halfYearlyPrice as Double) / 6.0

let currencyFormatter = NumberFormatter()
currencyFormatter.usesGroupingSeparator = true
currencyFormatter.numberStyle = .currency
currencyFormatter.locale = Locale.init(identifier: "en-US")

if let formattedPrice = currencyFormatter.string(from: perMonthPrice as NSNumber) {
    print("formattedPrice: ", formattedPrice)
    print("\(formattedPrice) / month")
}

The output is

formattedPrice:  $12.00
$12.00 / month

I'm wondering how can I ensure the formattedPrice is 11.99?

Thanks in advance.

CodePudding user response:

While you should use Decimal to more accurately represent base-10 values, using a double isn't the root cause of your problem here.

The default roundingMode of a NumberFormatter is .halfEven, which is going to round 11.998 up to 12.00. In fact any value >= 11.995 will end up as 12.00.

You need to set the rounding mode to .down.

let halfYearlyPrice = Decimal(71.99)
var perMonthPrice =  halfYearlyPrice / 6

let currencyFormatter = NumberFormatter()
currencyFormatter.usesGroupingSeparator = true
currencyFormatter.numberStyle = .currency
currencyFormatter.locale = Locale.init(identifier: "en-US")
currencyFormatter.roundingMode = .down

if let formattedPrice = currencyFormatter.string(from: perMonthPrice as NSNumber) {
    print("formattedPrice: ", formattedPrice)
    print("\(formattedPrice) / month")
}

Output:

formattedPrice: $11.99

$11.99 / month

You will get this result even if you don't use Decimal, but rounding errors can accrue if you perform numerous currency operations using floating point values rather than `Decimal.

  • Related