iOS 浮点型精度缺失问题处理
在日常接收后台返回的数据时,有时候会按浮点型返回回来,可能就会出现精度缺失的问题,后台返回的是3.10,但我们实际接收后会变成3.0999999,造成显示的问题,如果是涉及到金钱的计算,对一个字符串进行[double value]之后,也可能会造成上述的问题,3.10乘以2,本应是6.20,但实际上可能变成了3.09999*2,数值就发生了变化,如何防止此类情况,需要使用到NSDecimalNumber这个对象去处理
NSDecimalNumberHandler handler1 = [NSDecimalNumberHandler decimalNumberHandlerWithRoundingMode:NSRoundDown scale:doct raiseOnExactness:NO raiseOnOverflow:NO raiseOnUnderflow:NO raiseOnDivideByZero:YES];
/
roundingMode 要使用的舍入模式,有四种值:
NSRoundPlain, 四舍五入
NSRoundDown, 只舍不入
NSRoundUp, 只入不舍
NSRoundBankers 四舍六入, 中间值时, 取最近的,保持保留最后一位为偶数
scale 结果保留几位小数
raiseOnExactness 发生精确错误时是否抛出异常,一般为NO
raiseOnOverflow 发生溢出错误时是否抛出异常,一般为NO
raiseOnUnderflow 发生不足错误时是否抛出异常,一般为NO
raiseOnDivideByZero 被0除时是否抛出异常,一般为YES
*/
这个方法有防止四舍五入的选项,NSRoundDown
因为在很多时候,3.455这个浮点要转成字符串的时候,使用
[NSString stringWithFormat:@"%.2f",3.455];
会变成3.46,默认帮你进了以为,导致会发生与其他数值相加的时候,会莫名的多了几分几毛的情况,并且展示的内容跟实际的数字是对不上的。
所以要使用好NSDecimalNumber这个对象处理金融类的数字的精度问题。
-
(NSString *)transformDecimalNumberByNumber:(double)number andDoct:(NSInteger)doct {
NSDecimalNumber *decNumber = nil;
NSDecimalNumberHandler *handler1 = [NSDecimalNumberHandler decimalNumberHandlerWithRoundingMode:NSRoundDown scale:doct raiseOnExactness:NO raiseOnOverflow:NO raiseOnUnderflow:NO raiseOnDivideByZero:YES];
NSString *numberString = [NSString stringWithFormat:@"%.5f",number];
NSDecimalNumber * numDecimal = [[NSDecimalNumber alloc] initWithString:numberString];
decNumber = [numDecimal decimalNumberByRoundingAccordingToBehavior:handler1];
return [decNumber stringValue];
}
这个可以限定返回的位数字符串。