OC,iOS浮点型数据的计算不正确问题
举个例子,有时候float类型的数据参与计算的时候,如果要求精度高的话,往往可能出现各种各样特别神奇的问题,所以NSDecimalNumber 应运而生。NSDecimalNumber继承自NSNumber,用于对浮点型数据的精度计算
举个例子
float a = 10.33;
float b = 10.3;
NSLog(@"a * b = %f",a * b);
NSLog(@"a + b = %f",a + b);

解决方案
第一种解决方案
如果准确的知道最大的小数保留位数,可以先去整,在计算,比方一下的方法
float a = 10.33;
float b = 10.3;
float c = (a * 100) * (b * 100);
float d = a * 100 + b * 100;
NSLog(@"a * b = %f",c / 10000.0);
NSLog(@"a + b = %f",d / 100.0);

第二种解决方案
NSDecimalNumber *a = [NSDecimalNumber decimalNumberWithString:@"10.33"];
NSDecimalNumber *b = [NSDecimalNumber decimalNumberWithString:@"10.3"];
NSDecimalNumber *c = [NSDecimalNumber decimalNumberWithString:@"2"];
NSLog(@"a + b = %@",[a decimalNumberByAdding:b]);
NSLog(@"a - b = %@",[a decimalNumberBySubtracting:b]);
NSLog(@"a * b = %@",[a decimalNumberByMultiplyingBy:b]);
NSLog(@"a / b = %@",[a decimalNumberByDividingBy:b]);
NSLog(@"a / b = %@",[a decimalNumberByDividingBy:b]);
NSLog(@"a的2次方 %@",[a decimalNumberByRaisingToPower:2]);
NSLog(@"a * 10的2次方 %@",[a decimalNumberByMultiplyingByPowerOf10:2]);
NSLog(@"a * 10的2次方 %@",[a decimalNumberByMultiplyingByPowerOf10:2]);

NSDecimalNumberHandler的使用
/*
NSRoundPlain:四舍五入 NSRoundDown:向下取正 NSRoundUp:向上取正 NSRoundBankers:(特殊的四舍五入,碰到保留位数后一位的数字为5时,根据前一位的奇偶性决定。为偶时向下取正,为奇数时向上取正。如:1.25保留1为小数。5之前是2偶数向下取正1.2;1.35保留1位小数时。5之前为3奇数,向上取正1.4)
scale:精确到几位小数
raiseOnExactness:发生精确错误时是否抛出异常,一般为NO
raiseOnOverflow:发生溢出错误时是否抛出异常,一般为NO
raiseOnUnderflow:发生不足错误时是否抛出异常,一般为NO
raiseOnDivideByZero:被0除时是否抛出异常,一般为YES
*/
NSDecimalNumberHandler *roundUp = [NSDecimalNumberHandler
decimalNumberHandlerWithRoundingMode:NSRoundPlain
scale:2
raiseOnExactness:NO
raiseOnOverflow:NO
raiseOnUnderflow:NO
raiseOnDivideByZero:YES];
NSDecimalNumber * inputNumber = [[NSDecimalNumber alloc]initWithString:@"10.0790001"];
NSDecimalNumber * number = [inputNumber decimalNumberByRoundingAccordingToBehavior: roundUp];
NSLog(@"%@",number);//10.08
总结
因为第一种方案需要准确知道精度,如果精度改了,就可能达不到我们想要的效果,代码需要重构,不建议使用。
浙公网安备 33010602011771号