OC中小數(shù)的精確計算

問題源于自己做的一個字符串單位換算的擴展方法,目的是把一大串數(shù)字轉(zhuǎn)換成萬、百萬等為單位。
最開始的時候,思路很簡單 直接把String轉(zhuǎn)成float(float最高能表示到3.4*10^38,一般來說夠用了),判斷下要顯示哪個單位,除一下就好了,然后就有了以下的代碼:

+(NSString *)unitStringFromString:(NSString *)numberStr{
    NSString *resultStr = nil;
    CGFloat nfloat = [numberStr floatValue];
    CGFloat resultFloat = 0;
    NSString *resultUnit = @"";
    //0~5位數(shù)不變,6~8位數(shù)轉(zhuǎn)換為**萬,9-12位數(shù)轉(zhuǎn)換為**億,12位數(shù)以上轉(zhuǎn)化為**萬億
    if (nfloat/100000<1) {
        return numberStr;
    }else if(nfloat/100000000<1){
        resultFloat = nfloat/10000.f;
        resultUnit = @"萬";
    }else if(nfloat/1000000000000<1){
        resultFloat = nfloat/100000000.f;
        resultUnit = @"億";
    }else{
        resultFloat = nfloat/1000000000000.f;
        resultUnit = @"萬億";
    }
    //這里直接保持小數(shù)點后所有位數(shù),并去除多余的0
    resultStr = [NSString stringWithFormat:@"%@%@",@(resultFloat),resultUnit];
    //或者直接保留兩位小數(shù)
    //resultStr = [NSString stringWithFormat:@"%.2f%@",resultFloat,resultUnit];
    return resultStr;
}

那么問題來了:當保留所有小數(shù)位數(shù)的時候,得出來的結果與預期的并不相同,例如:

numberStr = @"108649330";
全部的輸出結果為=>
resultStr = @"1.08649328億";
保留兩位小數(shù)的結果為=>
resultStr = @"1.09億";

我們發(fā)現(xiàn)保留兩位小數(shù)時的數(shù)據(jù)沒有問題,但是全部輸出時,會有一定的誤差。
我們想要的效果是,去除小數(shù)點后多余的0,并且最多保留兩位小數(shù),所以添加了一些代碼:

    //這里保留兩位小數(shù),并去除多余的0
    NSString *tempStr = [NSString stringWithFormat:@"%.2f",resultFloat];
    resultStr = [NSString stringWithFormat:@"%@%@",@([tempStr floatValue]),resultUnit];

這樣就能達到想要的效果了。
但是,有沒有更精確的方法來計算兩個浮點數(shù)的運算呢?
后來發(fā)現(xiàn)了這篇文章 關于OC中的小數(shù)精確計算---NSDecimalNumber
文中,提到了NSDecimalNumber是用于OC中精確計算的,所以我將上面的代碼修改為:

+(NSString *)unitStringFromString:(NSString *)numberStr{
    NSString *resultStr = nil;
    NSDecimalNumber *decNumber = [NSDecimalNumber decimalNumberWithString:numberStr];
    NSString *devisor;
    NSString *resultUnit = @"";
    CGFloat nfloat = [numberStr floatValue];
    //0~5位數(shù)不變,6~8位數(shù)轉(zhuǎn)換為**萬,9-12位數(shù)轉(zhuǎn)換為**億,12位數(shù)以上轉(zhuǎn)化為**萬億
    if (nfloat/100000<1) {
        devisor = @"1";
        resultUnit = @"";
    }else if(nfloat/100000000<1){
        devisor = @"10000";
        resultUnit = @"萬";
    }else if(nfloat/1000000000000<1){
        devisor = @"100000000";
        resultUnit = @"億";
    }else{
        devisor = @"1000000000000";
        resultUnit = @"萬億";
    }
    NSDecimalNumber *divisorNumber = [NSDecimalNumber decimalNumberWithString:devisor];
    NSDecimalNumber *resultDec = [decNumber decimalNumberByDividingBy:divisorNumber];
    //直接輸出結果
    //resultStr = [resultDec stringValue];
    //resultStr = [NSString stringWithFormat:@"%@%@",resultStr,resultUnit];
    //這里保留兩位小數(shù),并去除多余的0
    NSString *tempStr = [NSString stringWithFormat:@"%.2f",[resultDec floatValue]];
    resultStr = [NSString stringWithFormat:@"%@%@",@([tempStr floatValue]),resultUnit];
    return resultStr;
}

以上,問題解決。

最后編輯于
?著作權歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容