将NSDecimalNumber转换为NSString时,NSNumberFormatter舍入不正确

时间:2014-02-12 19:20:54

标签: ios objective-c nsnumberformatter nsdecimalnumber

我在尝试计算应用于产品的税额并在标签中显示时运行以下代码。此税应使用银行家四舍五入(与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);

这输出以下内容:

tax : 3.785272
textLabel : $3.79

使用NSNumberFormatterRoundHalfEven时,税收应该是3.78,而不是3.79。我无法弄清楚为什么它不尊重舍入模式。我认为它可能与NSNumberFormatterCurrencyStyle无法与NSNumberFormatterRoundHalfEven很好地相关,因此我将样式更改为十进制并将最小/最大小数位数设置为2,它仍然以完全相同的方式执行。

我认为NSNumberFormatterNSDecimalNumber进行交互可能会有些奇怪,所以我尝试了这段代码:

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];

但它仍然输出以下内容:

tax : 3.785272
textLabel : 3.79

我现在完全不知所措。有没有人发现我在这些方法中做错了什么?我更喜欢使用涉及NSNumberFormatter的第一种方法,因为这样可以避免我进行大量的重构,但如果我必须使用第二种方法来获得正确的答案,那就这样吧。

2 个答案:

答案 0 :(得分:2)

不,这看起来对我来说是正确的行为。如果你看一下RoundHalfEven的文档就说

  

向最近的整数舍入,如果等距则朝向偶数。

在你的情况下,3.785272 接近3.79而不是3.78,因此它等距,并且向均匀方向转数。

如果真正等距,它应该只舍入到偶数,在你的情况下3.785将舍入到3.78。

答案 1 :(得分:0)

您可以尝试:

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

帮助我并正常工作!