2011-06-30 8 views
6

W języku programowania C stała zmiennoprzecinkowa jest domyślnie typu podwójnego
, więc 3.1415 jest typu podwójnego, chyba że używa sufiksu "f" lub "F" do wskazania typu pływaka.Przypisz podwójną stałą do zmiennoprzecinkowej bez ostrzeżenia w C?

Zakładam, że const float pi = 3.1415 spowoduje ostrzeżenie, ale w rzeczywistości nie.

gdy próbuję je pod gcc z -Wall:

float f = 3.1415926; 
double d = 3.1415926; 
printf("f: %f\n", f); 
printf("d: %f\n", d); 
f = 3.1415926f; 
printf("f: %f\n", f); 
int i = 3.1415926; 
printf("i: %d\n", i); 

wynik jest:

f: 3.141593 
d: 3.141593 
f: 3.141593 
i: 3 

wynik (w tym podwójnego zmiennej) oczywiście utratę precyzji, ale kompilacji bez żadnego ostrzeżenia.
więc co zrobił kompilator z tym? czy coś źle zrozumiałem?

Odpowiedz

7

-Wall nie daje ostrzeżenia o utracie precyzji, obcięcie wartości, itp, ponieważ te ostrzeżenia są denerwujący hałas i "naprawianie" ich wymaga porządkowania poprawnego kodu przy stosach brzydkich odlewów. Jeśli chcesz ostrzeżenia o takim charakterze, musisz je włączyć jawnie.

Również korzystanie z nie ma nic wspólnego z precyzją rzeczywistych zmiennych, tylko precyzja jest drukowana w printf, która domyślnie wynosi 6 miejsc po przecinku dziesiętnym.

+0

Wariantowa natura 'printf' zapewnia, że ​​przepływy są niejawnie rzutowane na podwójne, gdy są przekazywane? –

+0

Tak, chociaż jest to raczej niezwiązane z pytaniem OP. –

+0

Zastanawiam się, która z nich jest większa: liczba błędów, które przechwytuje komunikat "możliwa utrata precyzji z double to float", lub liczba błędów, które wynikają z kodu programisty, który musi wyraźnie zmusić wiele rzeczy do 'float' do zrobienia kompilator szczęśliwy, także zmusza do "unoszenia" czegoś, co nie powinno być [np 'const float oneTenth = 1.0f/10.0f; wartość pływająca1 = 8,0 f * jedennasta; double value2 = 4.0f * oneThoth; 'Zauważ, że gdyby' onethenth' mogło być "double", wszystko by działało idealnie. – supercat

2

%f może być używany z float i double. Jeśli chcesz większą precyzją Użyj

printf("f: %.16f",d); 

I to jest to, co dzieje się pod maską:

float f = 3.1415926; // The double 3.1415926 is truncated to float 
double d = 3.1415926; 
printf("f: %f\n", f); 
printf("d: %f\n", d); 
f = 3.1415926f;  // Float is specified 
printf("f: %f\n", f); 
int i = 3.1415926; // Truncation from double to int 
printf("i: %d\n", i); 
+0

Czy nie powinno to być '% lf' dla podwójnego? –

+3

@sharth: 'lf' i' f' są różne dla 'scanf', ale to samo w' printf' – Jacob

1

Jeśli chcesz otrzymywać ostrzeżenia o tym, uważam, że -Wconversion oznacza je w głównej linii poleceń gcc-4.3 i nowszych.

Jeśli używasz OS X, -Wshorten-64-to-32 oznaczał je w GCC Apple'a od gcc-4.0.1. Wierzę, że klang pasuje do głównego zachowania gcc.

Powiązane problemy