2014-10-04 16 views
6

jeśli napisać kod w C++:C++ podwójnie długo długo

long long d = 999999998.9999999994; 
cout<<d; 

dostaję wyjście: 999999999 (zaokrąglając w górę)

Ale wyjście z tego kodu:

long long d = 999999998.9999994994; 
cout<<d; 

jest 999999998 (zaokrąglanie w dół)

Czy to ma coś wspólnego z precyzją. Czy jest jakiś sposób, abym mógł zmienić precyzję. Funkcja floor() również daje takie samo wyjście.

Zauważyłem również, że jeśli przypisać wartość 8.9999994994 lub 8.9999999994 do d (powyżej zmiennej). Wyjście to 8.

+0

Możesz jednoznacznie dodać 0,5 i rzucić podwójnie na długo. –

+0

Obsługa C++ 11? Literały zdefiniowane przez użytkownika mogą pomóc. – Yakk

+0

@OleksandrVerhun Możesz to zrobić, ale jeśli twoim celem jest zaokrąglenie liczby zmiennoprzecinkowej do najbliższej liczby całkowitej, nie powinieneś tego robić. http://blog.frama-c.com/index.php?post/2013/05/02/nearbyintf1 –

Odpowiedz

10

999999998.9999999994 nie jest dokładnie zakodowania w double, dzięki czemu rzeczywista wartość jest jednym z dwóch do zakodowania numerami na jednej stronie 999999998.9999999994 - albo 999999998.99999988079071044921875 lub 999999999 (zakładając, że w formacie IEEE 754 binary64), wybrane w sposób realizacji określone. Większość systemów domyślnie zaokrągli do najbliższego, tworząc 999999999.

Wynik netto jest taki, że w tych systemach podczas pisania 999999998.9999999994 kończy się to dokładnie tak samo jak pisanie 999999999.0. Stąd późniejsza konwersja daje 999999999 - konwersja z liczby zmiennoprzecinkowej na liczbę całkowitą zawsze się obcina, ale tutaj nie ma nic do obcięcia.

W przypadku najbardziej reprezentatywnych liczb: 999999998.999999523162841796875 i 999999998.99999940395355224609375. Każda z nich produkuje 999999998 po obcięciu. Podobnie, z 8.9999999994, najbliższymi możliwymi do przedstawienia liczbami są 8.999999999399999950355777400545775890350341796875 i 8.9999999994000017267126168007962405681610107421875, a każdy z nich wytworzy 8 po obcięciu.

4
long long d = 999999998.9999999994; 

Najbliższa wartość 999999998.9999999994 że double może oznaczać to 999999999.0 - pamiętać, że punkty pływające mają skończoną dokładność;).
Dlatego obcięcie miejsc po przecinku daje 999999999, i to jest zapisane w d.

Korzystanie dosłownym z L -suffix rzeczywiście doprowadzić do 999999998 zapisywane w d - long double ma większą precyzję.

long long d = 999999998.9999994994; 

Najbliższa wartość 999999998.9999994994 że double może reprezentować jest rzeczywiście poniżej 999999999 - około 999999998.999999523 na moim komputerze. Obcięcie miejsc po przecinku następnie daje 999999998 i jest przechowywane w d.