I am running the following code when attempting to calculate the amount of tax applied to a product and display it in a label. This tax should use bankers rounding (same as NSNumberFormatterRoundHalfEven)

NSNumberFormatter *formatter = [[NSNumberFormatter alloc] init];
[formatter setNumberStyle:NSNumberFormatterCurrencyStyle];
[formatter setRoundingMode:NSNumberFormatterRoundHalfEven];

NSDecimalNumber *decimalTax = [NSDecimalNumber decimalNumberWithString:@"3.785272"];

NSLog(@" tax : %@", decimalTax);
NSString *rightText =  [formatter stringFromNumber: decimalTax];
NSLog(@" textLabel : %@", rightText);

This outputs the following:

tax : 3.785272
textLabel : $3.79

When using NSNumberFormatterRoundHalfEven, the tax should round to 3.78, rather than 3.79. I can't figure out why it isn't respecting the rounding mode. I thought it might have something to do with NSNumberFormatterCurrencyStyle not playing nicely with NSNumberFormatterRoundHalfEven, so I changed the style to decimal and set the minimum/maximum fractional digits to 2 and it still performs exactly the same way.

I thought it might be something strange going on with NSNumberFormatter interacting with NSDecimalNumber so I tried this code instead:

NSDecimalNumberHandler *numberHandler = [[NSDecimalNumberHandler alloc] initWithRoundingMode:NSRoundBankers scale:2 raiseOnExactness:YES raiseOnOverflow:YES raiseOnUnderflow:YES raiseOnDivideByZero:YES];

NSDecimalNumber *decimalTax = [NSDecimalNumber decimalNumberWithString:@"3.785272"];

NSString *rightText = [[decimalTax decimalNumberByRoundingAccordingToBehavior:numberHandler] description];

But it still outputs the following:

tax : 3.785272
textLabel : 3.79

I am completely at a loss for ideas now. Does anyone spot an error in what I'm doing in either of these methods? I prefer to use the first method involving NSNumberFormatter, as that would save me from doing a lot of refactoring, but if I have to use the second method to get a correct answer then so be it.

有帮助吗?

解决方案

No, that looks like the correct behavior to me. If you look at the documentation of RoundHalfEven it says

Round towards the nearest integer, or towards an even number if equidistant.

In your case 3.785272 is closer to 3.79 than it is to 3.78, thus it is not equidistant and should not round towards an even number.

It should only round to an even number if it was truly equidistant, in your case 3.785 would round to 3.78.

其他提示

You can try:

[formatter setRoundingIncrement:[NSNumber numberWithDouble:0.001]];

It is help me and working correctly!

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top