2013-03-22 20 views
15

widzę to cały czas:Jaki jest sens używania "f" podczas przypisywania wartości do CGFloat?

CGFloat someCGFloat = 1.2f; 

Dlaczego 'f' używany? Jeśli CGFloat jest zdefiniowany jako float, wartość zostanie przekonwertowana na float, a jeśli CGFloat zostanie zdefiniowana jako double, wartość zostanie przekonwertowana na double.

Czy należy się upewnić, że konwersja z double na float nie występuje? Po co to robić? Czy kompilator nie mógłby się tym zająć?

EDIT: Hmmm ... co odpowiedzieć, aby zaakceptować ... oba są bardzo dobre!

+1

Nie wiem o tym w deklaracji. Myślę, że f może być użyteczne, jeśli nie używasz stałej w stałym horyzoncie czasowym (np. 'SomeFloat = 3.0 * someOtherFloat' może w rzeczywistości powodować niepotrzebne konwersje w zależności od kompilatora.) Nie odpowiada jednak bezpośrednio na twoje pytanie. –

+0

@MaxE. Widzę. To pomocne, dzięki! – fumoboy007

+0

Czytelność nie powinna być dyskontowana. – GoZoner

Odpowiedz

8

1.0 domyślnie jest podwójny, jeśli prawidłowa wartość to 1.2, jest to rzutowanie niejawne, a wartość jest rzutowana z podwójnej na zmienną (rzutowanie nie jest operacją wykonawczą). W tym przypadku nie jest ważne, aby go nazwać 1.2f. Programiści najczęściej nadużywają tego, ale są przypadki, w których jest to naprawdę ważne.

Na przykład:

float var= 1.0e-45; 
NSLog(@"%d",var==1.0e-45); 

Wypisuje zero, ponieważ 1.0e-45 jest zbyt mała, aby być przechowywane w pojedynczej precyzji pływających punktu zmiennej, więc staje się równa zeru. Zapis var == 1.0e-45f zmienia wynik.

Używanie specyfikatorów formatu jest ważne głównie podczas pisania wyrażeń, a ponieważ lewa wartość jest zmiennoprzecinkową, można się spodziewać, że wyrażenie zostanie potraktowane jako zmienna, ale tak się nie dzieje.

Bardziej uderzający przypadek jest przy użyciu specyfikatora formatu l na numer, który zostaje przesunięty tak, aby stać się zero, a dostać zaskoczony wynikiem:

long var= 1<<32; // I assume that an int takes 4 bytes and a long 8 bytes 

wynik jest zero, a pisanie 1l < < 32 całkowicie zmienia wynik.

7

W Twoim urywku, po prostu przypisanie, nie potrzebujesz przyrostka "f", a w rzeczywistości nie powinieneś go używać. Jeśli CGFloat jest pojedynczą precyzją (jak w iOS), wtedy twoja wartość zostanie zapisana jako pojedyncza precyzja z lub bez "f", a jeśli CGFloat jest podwójną precyzją (jak na Mac OS), wtedy niepotrzebnie stworzysz pojedynczą wartość precyzji, która ma być zapisana podwójna precyzja.

Z drugiej strony, jeśli robisz arytmetykę, powinieneś uważać, aby użyć "f" lub nie używać go w odpowiedni sposób. Jeśli pracujesz z pojedynczą precyzją i umieścisz literał taki jak "1.2" bez "f", wówczas kompilator będzie promował inne operandy do podwójnej precyzji. A jeśli pracujesz z podwójną precyzją i dodajesz "f" (tak jak przydziału na Mac OS), stworzysz pojedynczą wartość precyzji tylko po to, aby natychmiast ją przekonwertować na podwójną.

Powiązane problemy