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

結果: 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM