2013-02-24 27 views
6

Szukam kuloodpornego sposobu konwersji zmiennych typu logicznego na prawdziwy typ, który będzie działał zarówno w ifort, jak i gfortran. Następujące prace w ifort, ale nie w gfortran:Konwertuj typ logiczny na podwójny w Fortranie

logical :: a 
real :: b 
a = .true. 
b = dble(a) 

Błąd wrzucony gfortran jest

b = dble(a) 
     1 
Error: 'a' argument of 'dble' intrinsic at (1) must be a numeric type 

Oczywiście .true. powinien zamapować na 1.d0 i .false. do 0.d0. Jaki jest najlepszy sposób na zrobienie tego?

+0

Za to, co warto, po włączeniu standardowego sprawdzania, na które aplikacja ifort powinna się skarżyć. Powodem, dla którego działa, jest to, że procesor ma rozszerzenie, które pozwala na niejawną konwersję logicznej na liczbę całkowitą, wówczas standard zapewnia konwersję z liczby całkowitej na rzeczywistą. Zauważ, że kiedy powiesz "oczywiście" wewnętrzną reprezentację .TRUE. będzie wyglądać zupełnie jak prawdziwa wartość 1.0, podczas gdy na * niektórych * procesorach wewnętrzna reprezentacja .TRUE. jest dokładnie taka sama jak wartość całkowita równa 1 (szczególnie, jeśli domyślna logiczna i LOGICZNA (C_BOOL) są tą samą reprezentacją). – IanH

+0

.true. = -1 jest również powszechne (wszystkie bity w liczbie całkowitej są ustawione na 1, co w uzupełnieniu 2 = -1). – WaywiserTundish

Odpowiedz

6

Nie jestem pewien, czy istnieje samoistne narzędzie, które to robi. Nie wiem, dlaczego ifort to akceptuje i przypuszczam, że jest to funkcja specyficzna dla kompilatora.

Opcją do tego, zwłaszcza, że ​​chcesz, aby było to zabezpieczone przed kulami, jest stworzenie własnej funkcji.

nie testowałem, ale może działać następuje:

double precision function logic2dbl(a) 
    logical, intent(in) :: a 

    if (a) then 
    logic2dbl = 1.d0 
    else 
    logic2dbl = 0.d0 
    end if 
end function logic2dbl 
+0

Powinieneś zwrócić wartość jako nazwę funkcji: 'logic2dbl = ...'. – sigma

+0

Należy również wymienić .eq. z .eqv. Przyjmuję, gdy odpowiedź jest poprawna pod względem składni! – Guillochon

8

Oprócz pisania funkcji do obsługi tego, można również korzystać bezpośrednio z wewnętrzną funkcję scalania: b = merge(1.d0, 0.d0, a). Lub możesz napisać zdefiniowany podprogram, który to robi, więc możesz po prostu wpisać b = a.

0

W gfortran używam TRANSFERu wewnętrznego dla tego rodzaju pracy. Zakładając całkowitą zmiennej my_int wówczas:

my_int = transfer(.false.,my_int) 

wynikiem my_int jest 0, jak oczekiwano.

+2

OP pyta o rzeczywiste zmienne ... – lodo

+1

'realvar = transfer (logiczny, 1)' (wystarczy wpisać literalną liczbę całkowitą 1 dla formy) działa (lub wydaje się). Nie wiem, jak przenośny to jest podany komentarz @WaywiserTundish – agentp