2012-06-10 15 views
13
#include <stdio.h> 
#include <float.h> 

int main() 
{ 
    printf("%f\n", FLT_MAX); 
} 

wyjścia z GNU:drukowanie bardzo dużych liczb zmiennoprzecinkowych

340282346638528859811704183484516925440.000000 

wyjścia z Visual Studio:

340282346638528860000000000000000000000.000000 

wykonaj ++ standardy C i C pozwalają oba wyniki? Czy może zlecają określony wynik?

Należy pamiętać, że FLT_MAX = 2^128-2^104 = 340282346638528859811704183484516925440.

+3

Standardy C i C++ nawet nie wymagają określonej reprezentacji zmiennoprzecinkowej. Kusi mnie więc myśl, że nie mogą nakazać konkretnego wyniku. – Mysticial

+0

@Mysticial Cóż, mogą nadal na ogół nakazać, że "dokładna wartość, która jest reprezentowana, musi być wydrukowana" lub coś w tym zakresie. – fredoverflow

+3

I Unix pwns Windows. Jeszcze raz. –

Odpowiedz

6

myślę, że odpowiednia część standardu C99 jest "Zalecana praktyka" z 7.19.6.1 P.13:

Dla e, E, f, F, g i G konwersje, jeśli liczba znaczących cyfr dziesiętnych wynosi co najwyżej DECIMAL_DIG, wtedy wynik powinien być poprawnie zaokrąglony. Jeśli liczba cyfr dziesiętnych jest większa niż DECIMAL_DIG, ale wartość źródłowa wynosi dokładnie reprezentowana przez cyfry DECIMAL_DIG, wynik powinien być dokładną liczbą z końcowymi zerami. W przeciwnym razie, wartość źródłowa jest ograniczona przez dwa sąsiednie znaki dziesiętne , które mają znaczące cyfry; wartość powstałego łańcucha dziesiętnych D powinien spełniać L < = D < = U, z dodatkowym zastrzeżeniem, że błąd powinien mieć prawidłowy znak dla aktualnego kierunku zaokrąglania.

Mam wrażenie, że pozwala to na pewną swobodę w tym, co można wydrukować w tym przypadku; więc moim wnioskiem jest to, że zarówno VS, jak i GCC są tutaj zgodne.

+0

Erm ... więc czy poprawne jest GNU lub Visual Studio? :) – fredoverflow

+2

Oboje są poprawni, tylko jeden ma większą precyzję. –

+5

@ColeJohnson: none ma więcej precyzji. GNU zdradza, że ​​tak jest, ale jego wynik jest nawet gorszy niż MSVC. Punkt zmiennoprzecinkowy reprezentuje * interwały *, a nie liczby. Zatem 340282346638528859811704183484516925440, 340282346638528859811704183484516925450 i 340282346638528860000000000000000000000 są wszystkie tymi samymi wartościami zmiennoprzecinkowymi (dla 64-bitowego ieee). [Lepsza rountina formatowania zmiennoprzecinkowego to taka, która daje ci możliwie najkrótszą reprezentację] (http://florian.loitsch.com/publications/dtoa-pldi2010.pdf). – ybungalobill

1

Oba są dopuszczone przez standard C (C++ tylko inports standard C)

Z draft version w sekcji 5.2.4.2.2 części 10

wartości podanych w poniższej listy powinny być zastąpione wyrażeniami z zdefiniowane wartości realizacji-de, które są większe niż lub równe tym przedstawionym:
- maksymalna zakodowania fi Nite chłodnicą liczba oating punktu (1 - b p) b Emax

FLT_MAX 1E+37 

i Visual C++ 2012 ma

#define FLT_MAX   3.402823466e+38F  /* max value */ 
+0

W praktyce wartość 'FLT_MAX' będzie taka sama na każdej platformie wykorzystującej zmiennoprzecinkowe IEEE-754. Więc nie o to tu chodzi. –

+0

@OliCharlesworth: OK, może "błąd" jest zbyt silny. Wywołuje nieokreślone wyniki. – wallyk

0

Kodeksu sama jest wadliwy, gdzie używa %f o wartości większej niż znaczeniu, która odbyła się w float lub double. Robiąc to, prosisz, abyś zobaczył "za kurtyną" co do bezsensownych bitów strażniczych lub innych szumów zmiennoprzecinkowych generowanych podczas konwersji na dziesiętne.

Oczywiście nie należy się spodziewać konsekwencji w opiłkach metalu powstałych po wykonaniu silnika w Hondzie w porównaniu z Toyotą. Nigdy nie myśl o rozsądnych oczekiwaniach takiej konsystencji.

Właściwym sposobem wyświetlania takich liczb jest użycie jednego z "naukowych" formatów, takich jak %g, pod warunkiem, że precyzja nie jest nadmiernie określona. W implementacjach IEEE-754 7 cyfr dziesiętnych ma znaczenie dla float, 15-16 dla double, około 19 dla long double i 34 dla __float128. Tak więc, na przykład, który podałeś, %.15g byłoby właściwe, zakładając, że jest na implementacji IEEE-754.

+1

Użycie '% f' nie jest" wadliwe ". Pytanie brzmi, dlaczego standard pozwala "za zasłoną". –

+0

@OliCharlesworth: OK, może "błąd" jest zbyt silny. Wywołuje nieokreślone wyniki. – wallyk

Powiązane problemy