1. 程式人生 > >iOS 浮點數格式字串比較大小 精度問題

iOS 浮點數格式字串比較大小 精度問題

計算機中float的儲存是不精確的。但是真正開發實踐的時候,或許只有出問題了,才會醒悟:哦,原來是這樣。這個問題在高大上的OC上同樣存在,稍不注意就會出現問題。尤其是涉及金融的計算比較資料方面顯得格外重要。

iOS開發中,請求後臺的介面,然後轉化為模型物件,最終轉化為NSString物件,然後控制元件顯示出來。這一切都是那麼的自然那麼的熟悉。但是如果伺服器返回的時浮點數格式的字串 並且客戶端還要用到這個資料去做加減乘除 比較大小這類操作,十有八九會出錯,如果再涉及金錢利潤的時候 這個責任就會無限放大。那麼怎樣解決呢?下面就看一個例子。

從服務端請求回的資料clearrate字串型別 需要乘以100再去和另外一個欄位exper比較大小 正常的做法是:

   CGFloat clearrate_float = [CUser.clearratefloatValue]*100.0;  

CGFloat per_assurescale_value = [model.per_assurescale_value floatValue];

     if (clearrate_float > per_assurescale_value) {

    }

  這樣看似沒有問題,但是看一下真是資料就會發現有坑

  真是返回資料是這樣的:

   {

    code = 0;

    data =     {

        clearrate = "1.05000000";

    };

   }

  但是實際除錯資料是這樣的:

     po clearrate_float

104.99999523162842

  這樣 返回的資料和自己轉成浮點數在乘以100就會有誤差! 那麼接下來用到這個資料比較還是加減乘除都會出錯!

*這事我們就要用到NSDecimalNumber這個類來處理浮點數的操作了

    //100.0轉化成NSDecimalNumber

    NSDecimalNumber *decimalNumber_dit = [NSDecimalNumberdecimalNumberWithFloat:100.0];

    //clearrate轉化成

NSDecimalNumber

NSDecimalNumber *decimalNumber_clearrate = [NSDecimalNumberdecimalNumberWithString:CUser.clearrate];

    //兩個數想乘

NSDecimalNumber *afterMultiplying_clearrate = [decimalNumber_clearrate decimalNumberByMultiplyingBy:decimalNumber_dit];

    //per_assurescale_value轉化成NSDecimalNumber

    NSDecimalNumber *decimalNumber_per_assurescale_value = [NSDecimalNumberdecimalNumberWithString:per_assurescale_value];

    //最終兩個浮點數比較大小變成NSDecimalNumber比較大小(如果有需求還可以加減乘除四則運算)

NSComparisonResult result_clearrate_float = [afterMultiplying_clearrate compare:decimalNumber_per_assurescale_value];

   //NSComparisonResult 的結果分為

     NSOrderedAscending  升序

     NSOrderedSame       相等

     NSOrderedDescending 降序

這樣再看一下實際除錯po出來的資料:

po decimalNumber_clearrate

1.05

po afterMultiplying_clearrate

105


這樣對NSDecimalNumber物件進行對比 四則運算都不會出錯了。大家要切記浮點數運算要特別小心!

大家有什麼建議 和 學習心得可以留言啊 歡迎大家共同進步微笑