2012-07-10 14 views
8

Chcę wiedzieć, czy istnieje prosta funkcja, którą mogę użyć takiej próbki. mamZaokrąglanie liczby zmiennoprzecinkowej w celu-c

float value = 1.12345; 

Chcę zaokrąglić go nazywając coś podobnego

float value2 = [roundFloat value:value decimal:3]; 
NSLog(@"value2 = %f", value2); 

I get „1,123” Czy istnieje Library lub domyślna funkcja dla tego lub powinienem napisać bloku kodu do tego typu obliczeń?

podziękowania za pomoc z góry

Odpowiedz

7

Korzystanie NSLog(@"%f", theFloat) zawsze wyprowadza sześć dziesiętnych, na przykład:

float theFloat = 1; 
NSLog(@"%f",theFloat); 

wyjściowa:

1.000000 

Innymi słowy, nigdy nie dostanie 1.123 za pomocą NSLog(@"%f", theFloat).

Cut-off po trzech miejsc po przecinku:

float theFloat = 1.23456; 
float newFLoat = (int)(theFloat * 1000.0)/1000.0; 
NSLog(@"%f",newFLoat); 

wyjściowa:

1.234000 

zaokrąglić do trzech miejsc po przecinku (z wykorzystaniem roundf()/lroundf()/ceil()/floor()):

float theFloat = 1.23456; 
float newFLoat = (int)(roundf(theFloat * 1000.0))/1000.0; 
NSLog(@"%f",newFLoat); 

Output :

1.235000 

Okrągły do ​​trzech miejsc po przecinku (brudny sposób):

float theFloat = 1.23456; 
NSString *theString = [NSString stringWithFormat:@"%.3f", theFloat]; 
float newFloat = [theString floatValue]; 
NSLog(@"%@",theString); 
NSLog(@"%f",newFloat); 

wyjściowa:

1.235 
1.235000 
+0

'% f' nie wyprowadza 6 miejsc po przecinku, it _rounds_ do 6 miejsc dziesiętnych. Rzeczywista wartość zmiennoprzecinkowa nie jest taka ładna. – Sulthan

+0

Działa to tylko dla pewnych wartości, które mają dokładne reprezentacje jako ułamki binarne.Nie działa w ponad 90% przypadków. – EJP

-1

spróbować

#import <math.h> 

float cutFloat(float number, int decimal) { 
    number = number*(pow(10,decimal)); 
    number = (int)number; 
    number = number/(pow(10,decimal)) ; 

    return number; 
} 
+0

to rozwiązanie nie będzie zaokrąglić liczbę . obniży go do określonego miejsca dziesiętnego. – nfarshchi

+0

I nawet nie zrobi tego właściwie w większości przypadków. – EJP

3

Do drukowania korzystanie wartość:

NSLog(@"value2 = %.3f", value2);

Zaokrąglanie do 3 miejsc po przecinku przed obliczeń naprawdę nie ma sensu, ponieważ float nie jest dokładną liczbą. Nawet jeśli zaokrąglisz go do 1.123, będzie to coś w rodzaju 1.122999999998.

Zasady:

  1. Zazwyczaj zaokrąglić w górę tylko wydrukować wynik - ciąg formatujący może go obsłużyć (patrz wyżej).
  2. Aby wykonywać dokładne obliczenia (np. Waluta), nie używaj zmiennoprzecinkowej, używaj NSDecimalNumber lub arytmetyki punktów stałych.
+0

Dziękuję za pomoc, ale w tej próbce powinienem użyć 'float', a także dowolny dodatkowy dziesiętny spowoduje pewien błąd w moich konkretnych obliczeniach. ale dziękuję za pomoc również – nfarshchi

+0

Próbowałem NSDecimalNumber i to było również świetne. dziękuję za sugestię. +1 – nfarshchi

+1

@nfarshchi To stwierdzenie jest sprzeczne z punktu widzenia. * Albo * musisz użyć float * lub * musisz mieć określoną liczbę miejsc po przecinku. Nie możesz * mieć obu: jest to matematyczna niemożliwość. – EJP

0

Zauważ, że "okrągły" niekoniecznie jest tak proste, to temat, jak myślisz. Na przykład:

DIY Calculator: Rounding Algorithms 101 zawiera listę 16 różnych metod zaokrąglania liczb.

Wikipedia:Rounding obejmuje wiele tego samego gruntu

I Cplusplus ma kod źródłowy bandą Rounding Algorithms które są łatwo przetłumaczyć na objective-c

Jak chcesz zaokrąglić będzie zależeć od kontekstu, co robisz dla danych.

I muszę podkreślić, że przepełnienie stosu ma już plethora of other questions about rounding in objective-c

1

Liczby zmiennoprzecinkowe nie mają miejsc po przecinku, mają miejsca binarnych. Liczby dziesiętne zawierają liczby dziesiętne. Nie można zaokrąglać liczb zmiennoprzecinkowych do określonej liczby miejsc po przecinku, chyba że dokonano konwersji na liczbę dziesiętną. Brak rutyny, metody, funkcji itp., Że wartość zmiennoprzecinkowa może ewentualnie wykonać to zadanie.

0
//Your Number to Round (can be predefined or whatever you need it to be) 
float numberToRound = 1.12345; 

float min = ([ [[NSString alloc]initWithFormat:@"%.0f",numberToRound] floatValue]); 
float max = min + 1; 
float maxdif = max - numberToRound; 
if (maxdif > .5) { 
    numberToRound = min; 
}else{ 
    numberToRound = max; 
} 

//numberToRound will now equal it's closest whole number (in this case, it's 1) 
0

Oto prosty sposób, aby to zrobić:

float numberToRound = 1.12345f; 
float remainder = numberToRound*1000.0f - (float)((int)(numberToRound*1000.0f)); 

if (remainder >= 0.5f) { 
    numberToRound = (float)((int)(numberToRound*1000.0f) + 1)/1000.0f; 
} 
else { 
    numberToRound = (float)((int)(numberToRound*1000.0f))/1000.0f; 
} 

dla dowolnego miejsca po przecinku, zastąpić 1000.0f w powyższym kodzie z

float mult = powf(10.0f, decimal); 
Powiązane problemy