iOS - 处理计算精度要求很高的数据,floatValue,doubleValue等计算不精确问题
Posted 公羽寒
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了iOS - 处理计算精度要求很高的数据,floatValue,doubleValue等计算不精确问题相关的知识,希望对你有一定的参考价值。
1、问题描述:服务器返回的double类型9.9、4.94的数字时 2、之前处理方式是 :(从内存、cpu计算来说double都是比较合适的,一般情况下都用double) goodsPrice.floatValue = 9.89999961 ==> 保留2位小数点9.89 3、现在的解决方法是: goodsPrice.doubleValue = 9.9000000000000003 ==> 保留2位小数点9.90 4、其他的解决方法: 服务器返回的数据全部设置为String类型,就不会出现这样的问题 从内存、cpu计算来说float都是比较合适的,一般情况下都用float
double 和 float 的区别是double精度高,有效数字16位,float精度7位。但double消耗内存是float的两倍,double的运算速度比float慢得多,C语言中数学函数名称double 和 float不同,不要写错,能用单精度时不要用双精度(以省内存,加快运算速度)。
解决方式之一:
当设计到金钱的计算.但是利用double类型数据会不稳定. 1:控制double类型的精度 double abc = 0.1 - 0.01 - 0.00001009; NSNumberFormatter *nf = [[NSNumberFormatteralloc ]init]; [nf setMaximumIntegerDigits:8]; NSNumber *number = [nfnumberFromString:[NSString stringWithFormat:@"%.8lf",abc]]; NSLog(@"number is ---%lf",[numberdoubleValue]); 2:对于double类型不损失精度的计算方法 -(CGFloat)addreeBackMoneyWithAmount:(CGFloat)amount ToMoney:(CGFloat)toMoney { NSString *amountStr = [NSString stringWithFormat:@"%.08lf",amount]; NSString *toMoneyStr = [NSString stringWithFormat:@"%.08lf",toMoney]; NSDecimalNumber *amountNum = [NSDecimalNumber decimalNumberWithString:amountStr]; NSDecimalNumber *toMoneyNum = [NSDecimalNumber decimalNumberWithString:toMoneyStr]; double xiaofee = 0.001210000; NSDecimalNumber *feeNum = [NSDecimalNumber decimalNumberWithString:[NSString stringWithFormat:@"%.8lf",xiaofee]]; NSDecimalNumber *resultNum = [amountNum decimalNumberBySubtracting:toMoneyNum]; NSDecimalNumber *subTracFeeNum = [resultNum decimalNumberBySubtracting:feeNum]; return [subTracFeeNum doubleValue];; }
举个栗子: 计算0.1*999999 看看会有什么结果?
- (void)testDecimalNumber { double d1 = 0.01; double d2 = 999999; double d3 = d1 * d2; NSLog(@"%@",n3); }
和我们想到的结果:9999.99不同
遇到这种问题解决办法如下:
- (void)testDecimalNumber { NSDecimalNumber* n1 = [NSDecimalNumber decimalNumberWithString:[NSString stringWithFormat:@"%f",d1]]; NSDecimalNumber* n2 = [NSDecimalNumber decimalNumberWithString:[NSString stringWithFormat:@"%f",d2]]; NSDecimalNumber* n3 = [n1 decimalNumberByMultiplyingBy:n2]; NSLog(@"%@",number); }
可以把float、double转成NSDecimalNumber类型的对象在计算。可以进行+、-、* 、/ 的运算。
用法 四舍五入:
-(NSString*)notRounding:(float)price afterPoint:(NSInteger)position { NSDecimalNumberHandler* roundingHandler = [NSDecimalNumberHandler decimalNumberHandlerWithRoundingMode:NSRoundPlain scale:position raiseOnExactness:NO raiseOnOverflow:NO raiseOnUnderflow:NO raiseOnDivideByZero:NO]; NSDecimalNumber* returnNumber; NSDecimalNumber* ouncesDecimal = [[NSDecimalNumber alloc]initWithFloat:price]; returnNumber = [ouncesDecimal decimalNumberByRoundingAccordingToBehavior:roundingHandler]; return [NSString stringWithFormat:@"%@",returnNumber]; }
测试数据:1.235
结果:
以上是关于iOS - 处理计算精度要求很高的数据,floatValue,doubleValue等计算不精确问题的主要内容,如果未能解决你的问题,请参考以下文章
iOS - Json解析精度丢失处理(NSString, Double, Float)