浮動小数点数の精度や値の範囲などの環境依存のパラメータを得るためにはMACHAR
関数を使う。現行バージョンのIDLがサポートしているプラットフォームでは、だいたい同じ結果になるはず。例外はIRNDで、 Windows、Linux、Mac (Intel)版IDLでは
IRND=5
(漸次アンダーフロー; gradual underflow が行われる), Solaris (SPARC)版IDLでは IRND=2
(flush to zero が行われる) となる。なお、いずれの場合も、XMIN
は正規化数の最小値を示す。以下は、IDL 8.2 (linux x86_64 m64) での実行結果。
IDL> HELP, MACHAR()
** Structure MACHAR, 13 tags, length=52, data length=52:
IBETA LONG 2
IT LONG 24
IRND LONG 5
NGRD LONG 0
MACHEP LONG -23
NEGEP LONG -24
IEXP LONG 8
MINEXP LONG -126
MAXEXP LONG 128
EPS FLOAT 1.19209e-07
EPSNEG FLOAT 5.96046e-08
XMIN FLOAT 1.17549e-38
XMAX FLOAT 3.40282e+38
IDL> HELP, MACHAR(/DOUBLE)
** Structure DMACHAR, 13 tags, length=72, data length=68:
IBETA LONG 2
IT LONG 53
IRND LONG 5
NGRD LONG 0
MACHEP LONG -52
NEGEP LONG -53
IEXP LONG 11
MINEXP LONG -1022
MAXEXP LONG 1024
EPS DOUBLE 2.2204460e-16
EPSNEG DOUBLE 1.1102230e-16
XMIN DOUBLE 2.2250739e-308
XMAX DOUBLE 1.7976931e+308
無限大を得るにはシステム定数 !VALUES.F_INFINITY
(FLOAT型)、!VALUES.D_INFINITY
(DOUBLE型)を使う。
与えられた値が無限大かどうかを判別するには FINITE(/INFINITY)
関数を使う。SIGN
キーワードで符号を判別できる。
非数を得るにはシステム定数 !VALUES.F_NAN
(FLOAT型)、!VALUES.D_NAN
(DOUBLE型)を使う。
与えられた値が非数かどうかを判別するには FINITE(/NAN)
関数を使う。SIGN
キーワードで符号を判別できる。
IDL> a = [!values.f_infinity, -!values.f_infinity, !values.f_nan, -!values.f_nan]
; 無限大・非数でないとき真
IDL> print, finite(a)
0 0 0 0
; 非数のとき真
IDL> print, finite(a, /nan)
0 0 1 1
; 無限大のとき真
IDL> print, finite(a, /infinity)
1 1 0 0
; 正の無限大のとき真
IDL> print, finite(a, /infinity, sign = 1)
1 0 0 0
; 負の無限大のとき真
IDL> print, finite(a, /infinity, sign = -1)
0 1 0 0
IDL 8.4以降では次のよう IDL_Variable クラスの静的メソッドを用いても書ける。ただし、配列に対してして行う場合、全ての要素について条件を満たすときのみ1を返す。
IDL> a = [!values.f_infinity, 1, 2, 3]
IDL> b = [!values.f_nan, 4, 5, 6]
; 全ての要素が無限大・非数でないとき真
IDL> print, a.IsFinite(), b.IsFinite()
0 0
; 全ての要素が非数のとき真
IDL> print, a.IsNaN(), b.IsNaN()
0 0
; 全ての要素が無限大のとき真
IDL> print, a.IsInfinite(), b.IsInfinite()
0 0
; 有限の要素のみ返す
IDL> print, a.Finite(), b.Finite()
1.00000 2.00000 3.00000
4.00000 5.00000 6.00000
0除算などの算術例外を報告するタイミングを変更するには !EXCEPT
システム変数を変更する。デフォルト値は !EXCEPT = 1
で、サブルーチン中で算術例外が発生した場合でも、サブルーチン終了後に算術例外が報告される。!EXCEPT = 2
にすると、算術例外が発生すると即座に報告されるが、パフォーマンスは低下する。!EXCEPT = 0
では算術例外を一切報告しない。
!EXCEPT = 1 ; default
print, 1/0, 1.0/0
print, !values.f_infinity - !values.f_infinity
end
上記のプログラムを実行すると、算術例外は最後にまとめて報告される。
1 Inf
-NaN
% Program caused arithmetic error: Integer divide by 0
% Program caused arithmetic error: Floating divide by 0
% Program caused arithmetic error: Floating illegal operand
!EXCEPT = 2
print, 1/0, 1.0/0
print, !values.f_infinity - !values.f_infinity
end
上記のプログラムを実行すると、算術例外が発生する度に報告されるため、発生箇所を容易に特定できる。
1 Inf
% Program caused arithmetic error: Integer divide by 0
% Program caused arithmetic error: Floating divide by 0
% Detected at $MAIN$ 2 /dev/tty
-NaN
% Program caused arithmetic error: Floating illegal operand
% Detected at $MAIN$ 3 /dev/tty
算術例外が発生したかどうかを調べるには CHECK_MATH
関数を用いる。ただし、IDLが算術例外を報告するタイミングで、CHECK_MATH
関数の返す結果も0にリセットされる。つまり、!EXCEPT = 1
のとき、プログラムが終了し、インタラクティブコマンドプロンプトに戻ると結果はリセットされる。!EXCEPT = 2
のときには、プログラムの実行が次のステートメントに移ると結果はリセットされる。
浮動小数点数の内部表現を変換するには BYTEORDER
プロシージャを用いる。単にエンディアンを変換するだけなら、SWAP_ENDIAN
関数か SWAP_ENDIAN_INPLACE
プロシージャも利用可能。