应用背景
今天,测试小姐姐跟我反馈四舍五入的数据不对,我研究后发现,之前编码随手使用了%.2f
来实现取两位小数的方法,而这种方法在iOS中并非是严格地四舍五入取两位小数,而是使用了“银行家算法”。
- 举个栗子:
得到结果为:NSLog(@"%.2f -- %.2f", 1.625, 1.635);
1.62 -- 1.64
- 简洁点,用一句口诀可以概括“银行家算法”:
四舍六入五考虑,五后非零就进一,五后为零看奇偶,五前为偶应舍去,五前为奇要进一
- 然而我们需求的是四舍五入
解决方案
-
NSDecimalNumber
作为NSNumber
的一个不可变子类,是苹果针对浮点型计算时存在精度计算误差的问题而提供的一个计算类,它是基于10进制的定点计算保证了精度不会缺失。同时也可以定制精度的取正类型:向上取正、向下去正、四舍五入等。相对与浮点类型的计算,NSDecimalNumber
提供了更加精准的计算。
- 用此方法进行四舍五入取两位小数的用法如下:
NSDecimalNumberHandler *behavior = [NSDecimalNumberHandler decimalNumberHandlerWithRoundingMode:NSRoundPlain scale:2 raiseOnExactness:NO raiseOnOverflow:NO raiseOnUnderflow:NO raiseOnDivideByZero:NO];
NSDecimalNumber *numResult1 = [NSDecimalNumber decimalNumberWithString:@"1.6350"];
NSLog(@"%@", [numResult1 decimalNumberByRoundingAccordingToBehavior:behavior]);
NSDecimalNumber *numResult2 = [NSDecimalNumber decimalNumberWithString:@"1.6250"];
NSLog(@"%@", [numResult2 decimalNumberByRoundingAccordingToBehavior:behavior]);
- 用c语言的算法
(floatValue * 100 + 0.5) / 100;