2013-08-05 40 views
23

我有一個iOS Objective-C如何獲得2個小數圓整浮點值?

float a = 1412.244019; 

,我需要一個被四捨五入到最接近的第二位小數像1412.24000000。我明白,如果我想介紹一個只有兩位小數,我使用%.2f,但事實並非如此。我需要新的數學原因作爲浮動。

我已經嘗試了幾個方法找到在stackoverflow沒有運氣。我使用的更明顯的一個,我在下面提到,但仍然沒有使用它。你能看出爲什麼魔術沒有發生?

PS:它有時做預期的效果,並非總是如此,這讓我想...嗯...

在此先感謝。

代碼:

float a = 1412.244019; 
NSLog(@"a is %f", a); //output a is 1412.244019 
a = [[NSString stringWithFormat:@"%.2f", a] floatValue]; 
NSLog(@"a is %f", a); //output a is 1412.239990 

編輯:

似乎當我使用該浮子上的上述手術後一樣,它正在考慮它是1412.240000 eventhough的NSLog的說...不同奇怪。 但我得到我想要的東西,所以浪費的時間追逐榮譽沒什麼:)

編輯我很想選擇你所有的正確答案,但因爲我只能選擇一個,我選擇的第一個好答案附加說明(最後兩個)。

回答

49

你試過嗎?

CGFloat val = 37.777779; 

CGFloat rounded_down = floorf(val * 100)/100; /* Result: 37.77 */ 
CGFloat nearest = floorf(val * 100 + 0.5)/100; /* Result: 37.78 */ 
CGFloat rounded_up = ceilf(val * 100)/100;  /* Result: 37.78 */ 

來源:Rounding Number to 2 Decimal Places in C

補全:你剛纔沒有關於電腦如何存儲的浮動值控制。

所以這些舍入值可能並不完全是「顯而易見的」十進制值,但它們會非常接近,這是您將擁有的最大保證。

+0

已經嘗試過了,看到你已經在另一篇文章中發佈了這種方法。但NSLog仍然給出相同的答案(嘗試自己)。但請參閱上面的編輯。儘管NSLog給出了「錯誤」的格式,但它正確地使用它。 –

+0

就像我在編輯中所說的那樣,我不可能在浮點數中獲得完整的精度 –

+0

我明白了。它正在以我想要的方式進行計算。我只是覺得這很奇怪,因爲那樣你就永遠無法使用精確的算術? –

2

您可以將a乘以100.0,也可以加上0.5進行舍入,然後取出結果的整數值。然後可以使用/ 100來獲取小數點前的值和%100來得到兩位小數。

+0

我想這樣做,沒有運氣。看到上面的編輯(在兩分鐘內) –

2

您不能強制浮點值。浮點數設計得有些近似,因爲浮點數的大小可能很大,並且由於只有很多位可以使用,它可以接近,但不能精確地表示十進制數。

一個建議是做所有的算術整數,乘以100,然後除以當你想顯示你的最終結果。你可能有太大的數字會禁止這個。

+0

我喜歡你的答案,我想我將不得不尋找另一種方式。但請參閱上面的編輯。儘管NSLog給出了「錯誤」的格式,但它正確地使用它。 –

+0

NSLog告訴你真相......但你可能正在使用其他的格式化/算術來平衡(正如float算術的設計)以使你接近真正的答案。但是你會發現有時候它符合你的期望,有時候它有這些不應該在那裏的小數,或者數字很短。當您打印答案時,或者您嘗試比較兩個浮點數(即2.0!= 5.0 - 3.0)時,這一點最爲明顯。如果你需要精確的,精確的算術總是正確的2位小數,你應該使用整數如上和/ 100. –

5

與最接近的值爲1412.24即float可以有1412.239990234375。有沒有操作,可以產生一個更接近的float,因爲float對象的格式不代表任何更接近的值。要求在float中代表1412.24就像在int中要求代表2.5。它根本無法完成。處理這種

選項包括:

  • 您可以使用顯示「1412.24」使用的格式,而無需更改基礎float對象。
  • 您可以使用double來拉近(更接近),但它仍然不會完全是1412.24。
  • 您可以將float的值縮放爲可表示的值(例如,以其他單位測量,以便您想要的值全都可以在float中精確表示)。
  • 您可以使用不同的數據類型,例如NSDecimal
+0

我appreaciate你的答案,我想我將不得不尋找另一種方式。但請參閱上面的編輯。儘管NSLog給出了「錯誤」的格式,但它正確地使用它。我會看看如果使用上述方法之一獲得更好的結果。 –

+1

@ B-Man,C'float'類型不能保證完美舍入。如果您需要,請使用其他數據類型。你可以滾動你自己並保持NSInteger值爲100的值,或者你可以使用其他數據類型,如[NSDecimal](https://developer.apple.com/library/mac/#documentation/Cocoa/Reference/Foundation /Classes/NSDecimalNumber_Class/Reference/Reference.html)。 – bshirley

10

你這樣做,在Objective-C的完全一樣,你在C將:

double notRounded = ...; 
double rounded = round (notRounded * 100.0)/100.0; 

不要使用float - 除非你可以給別人解釋什麼您的具體原因是使用float超過一倍。浮動的精度非常有限。使用ceil或floor是愚蠢的,因爲有一個名爲「round」的非常好的標準函數。

無論是浮動還是雙可以正好表示大多數小數值,如12.24。因爲它有更高的精確度,雙倍會讓你更接近12.24。因此,NSLog很可能會顯示一些奇怪的數字(float)12.24,比如12.23999997394或其他,但它可能會顯示12.24的double。

+1

感謝您的回答。雙是要走的路。我之前已經選擇了一個答案,所以我想我只能提出你的答案。謝謝你的時間來解釋,非常感謝。 –

1

錯誤在這行

a = [[NSString stringWithFormat:@"%.2f", a] floatValue]; 

正確它

a = [NSString stringWithFormat:@"%.02f", a];