2011-08-25 9 views
6

C++: Jaki jest format formatu printf() dla float? (Visual C++)C++: Jaki jest format specyfikacji printf() dla "float"?

Kiedyś używałem %g dla float i %lg dla double.

Wygląda na to, że specyfikacja została zmieniona, a float jest niezdefiniowana, a double jest %g.

Mam w pamięci bity, które wypisuję, więc odlewanie nie wchodzi w grę.

Czy istnieje sposób, aby wydrukować wartości float przy użyciu printf()?

Aktualizacja:

Kod ten został napisany dla testów jednostkowych rodzajowe C++ bibliotekami używane od wbudowanego systemu. Oto, co musiałem zrobić, aby uruchomić float. Kod jest w funkcję szablonu:

template <typename T,typename TTYP,typename Ttyp,int bits,bool IsSigned> 
Error testMatrixT() 
{ ... 

Oto wycinek kodu:

if (typeid(Ttyp) == typeid(float)) {  
    float64 c = *(float32*)&Tp(row,col); 
    float64 a1 = *(float32*)&Arg1(row,col); 
    float64 a2 = *(float32*)&Arg2(row,col); 
    float64 e = *(float32*)&Exp(row,col); 
    m_b = (c == e); 
    _snprintf(m_acDiag, sizeof(m_acDiag)-1 
     , "add(Arg1,Arg2): arg1=%g, arg2=%g, Expected=%g, Actual=%g, Result: %s" 
     , a1, a2, e, c, BOOL_PF(m_b)); 
} else { 
    ... 

Dość brzydka prawda? Używanie zmiennoprzecinkowych jako argumentów daje złe wyniki. Może z powodu używania _snprintf()? Lat temu użyłbym %lg i byłoby OK. Nigdy więcej.

+1

To jest trzecie lub czwarte pytanie, które widziałem, w ciągu wielu dni, na temat drukowania float! – Praetorian

+0

Nie wspomniałeś o tym, co się stanie, jeśli użyjesz% g. Ale% g nie jest domyślną wartością float. – steve

+1

@steve: '% g' działa w trybie float, ponieważ jest promowane do podwojenia. –

Odpowiedz

16

podwójne i pływak używać tych samych specyfikatorów format z printf (%a , %e, %f i %g). Jest tak, ponieważ printf jest funkcją variadic. Wszelkie argumenty zmiennoprzecinkowe są pośrednio promowane do podwójnego przed wywołaniem; nie można faktycznie przekazać float do printf.

1
printf("float: %f", floatValue); 

lub jeśli chcesz wykładniczej notacji:

printf("float: %e", floatValue); 
+0

Lub jeśli chcesz mieć stały punkt lub wykładniczy: 'printf (" float:% g ", floatValue);' –

4

Na pytanie w tytule: Nie ma nikogo/„% f”

Na pytanie w treści wiadomości: Tak i nie.

printf jest funkcją variadic. Wszystkie argumenty float są automatycznie promowane do double s. Drukujesz float, przekazując go do printf, ale żaden float nie osiąga funkcji printf.

1

Inni wskazali format drukowania float przy użyciu printf, ale ponieważ używasz C++, moją sugestią jest uniknięcie tego całkowicie.

Zamiast tego użyj strumieni C++, nie musisz się wtedy martwić o specyfikatory formatu. Jest również bezpieczny, natomiast printf nie jest.

#include <iostream> 

int main() 
{ 
    float f = 1.234; 
    std::cout << f << std::endl; 
} 

Jeśli masz tablicę bajtów zawierających pływaka, memcpy go do zmiennej typu float i wykorzystać powyższy kod.

+0

Skończyło się na użyciu strumieni, ale myślę, że jest to rozwiązanie tymczasowe, ponieważ jestem pewien, że w końcu uruchomimy to na osadzonej platformie bez obsługi STL. Wydaje mi się, że zmienne są przestarzałe, ponieważ nie ma specyfikacji formatu i nie działa jako argument dla printf, chyba że użyję go do podwójnego. –

1

%g zawsze był prawidłowym formatem dla wartości zmiennoprzecinkowej lub podwójnej (ponieważ argumenty zmiennopozycyjne są promowane do podwójnych dla funkcji wielodostępnych, takich jak printf).

%lg został dodany jako synonim dla %g (w C99, nie wiem kiedy i czy C++ go przyjął), prawdopodobnie dla lepszej symetrii z rodziną *scanf.

$Lg jest dla długich podwójnych.

Możesz zamienić g na f lub e w powyższym, w zależności od tego, jaki format wyjściowy chcesz.

+0

W wielu systemach C++ używa tego samego środowiska wykonawczego co C, więc jeśli biblioteka C używa standardu C99, to samo robi C++. – user877329

+0

@ user877329: True - ale nadal są biblioteki C, które nie obsługują C99 (Microsoft, na przykład, jeśli się nie mylę). –