Jak ustawić wartości podwójnej precyzji w Fortran

10

Ostatnio napotkałem dziwny problem z FORTRAN95. Zainicjowałem zmienne X i Y w następujący sposób:

X=1.0
Y=0.1

Później dodaję je razem i wydrukuję wynik:

1.10000000149012

Po zbadaniu zmiennych wydaje się, że 0,1 nie jest reprezentowane w podwójnej precyzji z pełną dokładnością. Czy jest jakiś sposób, aby tego uniknąć?

Paweł
źródło

Odpowiedzi:

21

Innym sposobem na to jest najpierw jawne określenie pożądanej precyzji w zmiennej za pomocą wewnętrznej wartości SELECTED_REAL_KIND, a następnie użycie jej do zdefiniowania i zainicjowania zmiennych. Coś jak:

INTEGER, PARAMETER :: dp = SELECTED_REAL_KIND(15)
REAL(dp) :: x
x = 1.0_dp

Zaletą robienia tego w ten sposób jest to, że możesz przechowywać definicję dpw module, a następnie w USEtym module, gdzie jest potrzebny. Teraz, jeśli kiedykolwiek chcesz zmienić precyzję swojego programu, musisz tylko zmienić definicję dpw tym jednym miejscu zamiast przeszukiwania i zastępowania wszystkich D0s na końcu inicjalizacji zmiennych. (Dlatego też odradzam używanie 1.0D-1składni do definiowania Y zgodnie z sugestią. Działa, ale utrudnia znalezienie i zmianę wszystkich instancji w przyszłości).

Ta strona na Fortran Wiki zawiera kilka dobrych dodatkowych informacji na temat SELECTED_REAL_KIND.

Barron
źródło
Zgadza się, powinno to być standardowe podejście.
Ondřej Čertík
A jak często ludzie naprawdę muszą ślepo zmieniać precyzję swoich programów, nie przechodząc procedury i procedury? Głównym powodem korzystania ze _dpschematu jest to, że precyzja jest jasno określona w przenośny sposób.
ja72
12

Zadeklarowałeś zmienne jako podwójną precyzję, ale zainicjowałeś je wartościami pojedynczej precyzji.

Mógłbyś napisać:

X=1.0d0
Y=1.0d-1

Poniższa odpowiedź Barrona to kolejny sposób na dokonanie dosłownej podwójnej precyzji, z tą zaletą, że pozwala ona zmienić precyzję zmiennych w późniejszym czasie.

Dan
źródło
1
Myślę, że należy stosować metodę 1.0_dp opisaną w poniższym poście.
Ondřej Čertík
1
I drugi komentarz @ OndřejČertík - odpowiedź Barrona jest najlepsza.
OscarB