简体   繁体   English

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

[英]NSNumberFormatter rounding incorrectly when converting NSDecimalNumber to NSString

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 ) 此税应使用银行家四舍五入(与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. 使用NSNumberFormatterRoundHalfEven ,税收应该是3.78,而不是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. 我认为它可能与NSNumberFormatterCurrencyStyle不能很好地与NSNumberFormatterRoundHalfEven一起使用,因此我将样式更改为十进制并将最小/最大小数位数设置为2,它仍然以完全相同的方式执行。

I thought it might be something strange going on with NSNumberFormatter interacting with NSDecimalNumber so I tried this code instead: 我认为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];

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. 我更喜欢使用第一个涉及NSNumberFormatter的方法,因为这样可以避免我进行大量的重构,但是如果我必须使用第二种方法来获得正确的答案,那么就这样吧。

No, that looks like the correct behavior to me. 不,这看起来对我来说是正确的行为。 If you look at the documentation of RoundHalfEven it says 如果你看一下RoundHalfEven的文档就说了

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. 在你的情况3.785272更接近 3.79比是3.78,因此它是等距和应该对周围的偶数。

It should only round to an even number if it was truly equidistant, in your case 3.785 would round to 3.78. 如果它真的是等距的话,它应该只舍入到偶数,在你的情况下3.785会舍入到3.78。

You can try: 你可以试试:

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

It is help me and working correctly! 这对我有帮助并正常工作!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM