2013-03-16 45 views
-1

我在四捨五入的iPhone應用程序浮動問題。iOS - 四捨五入浮游物()無法正常工作

float f=4.845; 
float s= roundf(f * 100.0)/100; 
    NSLog(@"Output-1: %.2f",s); 
     s= roundf(484.5)/100; 
    NSLog(@"Output-2: %.2f",s); 

Output-1: 4.84 
Output-2: 4.85 

讓我知道這是什麼問題以及如何解決這個問題。

+0

你期待什麼輸出? – 2013-03-16 07:49:53

+0

你想做什麼?你正在使用浮點數,而不是實數 – 2013-03-16 07:51:45

+1

執行'NSLog(@「%f」,4.845f * 100);''和'NSLog(@「%f」,484.5f);'看看它們是不是相等的 – 2013-03-16 07:51:59

回答

7

問題是,你還沒有意識到浮點的固有問題之一:大多數數字不能完全表示的事實(a)

這意味着4.845很可能是,在現實中,像4.8449999999999裏面,當你一輪吧,給你4.84而不是你所期望,4.85什麼。

你最終得到的價值還取決於你計算它的方式,這就是你得到不同結果的原因。

而且,當然,如果沒有權威What Every Computer Scientist Should Know About Floating-Point Arithmetic,沒有浮點「不準確」答案將會完成。


的(a)中的兩個精確功率的一定相似範圍內只有總和,可以準確地在IEEE754渲染。因此,例如,484.5

256 + 128 + 64 + 32 + 4 + 0.528 + 27 + 26 + 25 + 22 + 2-1)。

請參閱this answer瞭解更多關於IEEE754格式的內容。


至於解決它,你有幾個選擇。一種是使用double而不是float。這給你更多的精度和更大的數字範圍,但只會將問題進一步移開,而不是真正解決問題。由於0.1是IEEE754中的一個重複部分,所以沒有比特的數量(短缺無限)可以準確表示它。

另一種選擇是使用自定義的庫就像一個大的十進制類型,它可以表示任意精度小數(這是無限精度有些人慣於建議,因爲它是由內存的限制)。這將減少由二進制/十進制不匹配引起的錯誤。

您可能也想看看NSDecimalNumber - 這不會給你任意的精度,但它確實給出了一個精確的十進制表示的大範圍。

仍然會有不能表示的數字,例如PI或2的平方根或任何其他無理數,但它應該覆蓋大多數情況。如果確實需要處理這些其他值,則需要切換到符號數字表示。

+0

在Objective-C中,您可以使用'NSDecimalNumber'來避免這種問題。它不是一個「大十進制類型」,而是完全用十三位數字表示十進制數字。 – 2013-03-16 11:10:50

+0

是的,我們可以用NSDecimalNumber解決它,但我已經解決了解決方案NSString * str = [NSString stringWithFormat:@「%。2f」,(f * 100)]; float s = roundf([str floatValue]); – 2013-03-18 04:32:16

2

不像484.5可以精確表示爲float *4.845表示爲4.8449998(見this calculator如果你想嘗試其他數字)。乘以一百將數字保持在484.49998,正確地舍入到484


*精確表示是可能的,因爲它的小數部分 0.5是2的冪(即 2^-1)。