我在四捨五入的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
讓我知道這是什麼問題以及如何解決這個問題。
我在四捨五入的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
讓我知道這是什麼問題以及如何解決這個問題。
問題是,你還沒有意識到浮點的固有問題之一:大多數數字不能完全表示的事實(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.5
(28 + 27 + 26 + 25 + 22 + 2-1
)。
請參閱this answer瞭解更多關於IEEE754格式的內容。
至於解決它,你有幾個選擇。一種是使用double
而不是float
。這給你更多的精度和更大的數字範圍,但只會將問題進一步移開,而不是真正解決問題。由於0.1
是IEEE754中的一個重複部分,所以沒有比特的數量(短缺無限)可以準確表示它。
另一種選擇是使用自定義的庫就像一個大的十進制類型,它可以表示任意精度小數(這是不無限精度有些人慣於建議,因爲它是由內存的限制)。這將減少由二進制/十進制不匹配引起的錯誤。
您可能也想看看NSDecimalNumber
- 這不會給你任意的精度,但它確實給出了一個精確的十進制表示的大範圍。
仍然會有不能表示的數字,例如PI或2的平方根或任何其他無理數,但它應該覆蓋大多數情況。如果確實需要處理這些其他值,則需要切換到符號數字表示。
在Objective-C中,您可以使用'NSDecimalNumber'來避免這種問題。它不是一個「大十進制類型」,而是完全用十三位數字表示十進制數字。 – 2013-03-16 11:10:50
是的,我們可以用NSDecimalNumber解決它,但我已經解決了解決方案NSString * str = [NSString stringWithFormat:@「%。2f」,(f * 100)]; float s = roundf([str floatValue]); – 2013-03-18 04:32:16
不像484.5
可以精確表示爲float *,4.845
表示爲4.8449998
(見this calculator如果你想嘗試其他數字)。乘以一百將數字保持在484.49998
,正確地舍入到484
。
0.5
是2的冪(即
2^-1
)。
你期待什麼輸出? – 2013-03-16 07:49:53
你想做什麼?你正在使用浮點數,而不是實數 – 2013-03-16 07:51:45
執行'NSLog(@「%f」,4.845f * 100);''和'NSLog(@「%f」,484.5f);'看看它們是不是相等的 – 2013-03-16 07:51:59