ToDo:
IEEE_VALUEは、intrinsicモジュール内の関数であるが、intrinsic関数では無いので、parameterの初期化式に記述できないのが難点 (現状も初期化は、tfinfint_が行っている)
REAL型のXに対して、floor(X)はX以下の最大のINTEGERを返す関数なので、正の無限大に対しては、INTEGER表現域の最大値をを返すべきだと思うのですが、gfortran 6.4だとなぜか-2147483648 = 0x80000000を返してくる
内部的には、REAL->INTEGER変換で符号付き2の補数形式の32bit INTEGERの最小値-2147483648.0d0を変換できるようになっていて、符号付きの浮動小数点なので正の無限大が2147483648.0d0に打ち切られてから整数変換によって0x80000000へ変換が起こってるように考えたのだが、有限値2147483648.0d0のfloorは表現域の上限2147483647 = 0x7fffffffを返している
INTEGER型の表現域に解が存在しないtfloor(-Infinity)に対して2147483647が返ってくるのも謎である
実装バグっぽい気がする
use IEEE_ARITHMETIC use ISO_FORTRAN_ENV real(real64) :: a, pinf, ninf, nan pinf = IEEE_VALUE(dinf, IEEE_POSITIVE_INF) ninf = IEEE_VALUE(dinf, IEEE_NEGATIVE_INF) nan = IEEE_VALUE(nan, IEEE_QUIET_NAN) a = 2147483648.d0 b = -2147483649.d0 write(*,*)a,' -> ',floor(a) write(*,*)b,' -> ',floor(b) write(*,*)pinf,' -> ',floor(pinf) write(*,*)ninf,' -> ',floor(ninf) write(*,*)nan,' -> ',floor(nan) write(*,*)sign(nan,-1.d0),' -> ',floor(sign(nan,-1.d0)) end
カテゴリー: Admin | Emacs | EPICS | Fortran | FreeBSD | GCC | hgsubversion | IPv6 | KEKB | LHC | Lisp | LLVM | MADX | Ryzen | SAD | samba | tDiary | unix | WWW | YaSAI | お仕事 | イベント | 出張 | 宴会 | 数学 | 艦これ | 買いもの | 追記 | 雑記