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 *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物件進行對比 四則運算都不會出錯了。大家要切記浮點數運算要特別小心!
大家有什麼建議 和 學習心得可以留言啊 歡迎大家共同進步