2013-02-24 19 views
6

論理型変数をifortとgfortranの両方で動作する実数型に変換するための防弾方法を探しています。次のifortで動作しますが、のgfortranでないFortranで論理型をdoubleに変換してください

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

。 = -1も共通です(整数のすべてのビットは1に設定され、2の補数では-1となります)。 – WaywiserTundish

答えて

6

これを実行する組み込みツールがあるかどうかはわかりません。なぜifortがこれを受け入れるのかわからないし、コンパイラ固有の機能だと思うだろう。

このオプションは、特にあなたが弾丸にしたいので、あなた自身の関数を作成することです。私はこれをテストしていませんが、以下はうまくいくかもしれない

b = merge(1.d0, 0.d0, a)

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 = 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コメントが与えられても、どのように移植可能かわからない – agentp

関連する問題