2013-02-24 2 views
6

Я ищу пуленепробиваемый способ преобразования переменных логического типа в реальный тип, который будет работать как в ifort, так и в gfortran. Следующие работы в ifort, но не в gfortran:Преобразование логического типа в double в Fortran

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

Ошибка выброшен в gfortran является

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

Очевидно, .true. должен отображаться на 1.d0 и .false. до 0.d0. Каков наилучший способ сделать это?

+0

Для чего стоит, если вы включите стандартную проверку ifort, следует подать жалобу. Причина, по которой он работает, заключается в том, что процессор имеет расширение, которое допускает неявное преобразование логического в целое число, тогда стандарт предоставляет преобразование из целого в реальное. Обратите внимание, что когда вы говорите «очевидно» внутреннее представление .TRUE. не будет выглядеть абсолютно как реальное значение 1.0, а на * некоторых * процессорах - внутреннее представление .TRUE. точно такое же, как целочисленное значение 1 (особенно если логическое значение по умолчанию и LOGICAL (C_BOOL) являются одинаковым представлением). – IanH

+0

.true. = -1 также является общим (все биты в целочисленном наборе равны 1, что в дополнении 2 = -1). – WaywiserTundish

ответ

6

Я не уверен, есть ли встроенный инструмент, который делает это. Я не знаю, почему ifort принимает это, и я предполагаю, что это специфичная для компилятора функциональность.

вариант для этого, в частности, поскольку вы хотите, чтобы это было пуленепробиваемым, заключается в создании вашей собственной функции.

Я не проверял, но следующий может работать:

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

Вы должны вернуть значение в качестве имени функции: 'logic2dbl = ...'. – sigma

+0

Кроме того, вы должны заменить .eq. с .eqv. Я соглашусь, когда ответ будет синтаксически правильным! – Guillochon

8

В дополнение к написанию функции для обработки этого, вы можете также непосредственно использовать встроенную функцию слияния: b = merge(1.d0, 0.d0, a). Или вы можете написать определенную подпрограмму назначения, которая делает это, так что вы можете просто ввести b = a.

0

В gfortran я использую встроенный TRANSFER для этого типа работы. Предполагая переменную my_int целое число, то:

my_int = transfer(.false.,my_int) 

результат my_int равно 0, как и ожидалось.

+2

OP запрашивает реальные переменные ... – lodo

+1

'realvar = transfer (logical, 1)' (просто положить буквальное целое число 1 для плесени) работает (или кажется). Не уверен, насколько переносимым это дано @WaywiserTundish comment – agentp

Смежные вопросы