iOS - 处理计算精度要求很高的数据,floatValue,doubleValue等计算不精确问题

 

1、问题描述:服务器返回的double类型9.94.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

 

 

doublefloat 的区别是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

结果: 

 

posted @ 2018-08-01 14:57  公羽寒  阅读(5815)  评论(0编辑  收藏  举报