IDLは強い動的型付け言語である。変数の型は、変数に値が代入された時点で決まる。
COMPLEX
, 構造体, DCOMPLEX
, POINTER
, オブジェクト, LIST
, HASH
は複合型である。Type Codeは0~15の整数である。Type Code と Type NameはSIZE
関数などさまざまな関数で用いられる。
Type Code | Type Name | データ型 | 値の範囲 | 作成方法 | 型変換関数 | 配列作成関数 |
---|---|---|---|---|---|---|
0 | UNDEFINED |
変数が未定義であることを示す。!NULL |
a = !NULL , a = [] , a = {} |
|||
1 | BYTE |
8bit符号なし整数 | 0~255 | a = 1B |
BYTE |
BYTARR |
2 | INT |
16bit符号付き整数 | -32768~32767 | a = 1 , a = 1S [注3] |
FIX |
INTARR |
3 | LONG |
32bit符号付き整数 | -231~231-1 | a = 1L |
LONG |
LONARR |
4 | FLOAT |
32bit単精度浮動小数点数 (有効数字約6~7桁) | ±(1.175e-38~3.403e+38) | a = 1.0 , a = 1.0E [注4] |
FLOAT |
FLTARR |
5 | DOUBLE |
64bit倍精度浮動小数点数 (有効数字約14桁) | ±(2.225e-308~1.798e+308) | a = 1.0D |
DOUBLE |
DBLARR |
6 | COMPLEX |
複素数 (単精度浮動小数点数) | 実部・虚部ともにFLOATに同じ | a = COMPLEX(1.0, 1.0) または a = 1 + 1i [注5] |
COMPLEX |
COMPLEXARR |
7 | STRING |
可変長文字列 | 2 GiB (231-1 B)まで | a = 'abc' |
STRING |
STRARR |
8 | 構造体名(無名構造体のときはANONYMOUS ) (構造体の配列はSTRUCT ) [注1] |
構造体 | a = {name, tag: 0} または CREATE_STRUCT 関数 |
|||
9 | DCOMPLEX |
複素数 (倍精度浮動小数点数) | 実部・虚部ともにDOUBLE に同じ |
a = DCOMPLEX(1.0, 1.0) または a = 1d + 1di [注5] |
DCOMPLEX |
DCOMPLEXARR |
10 | POINTER |
ポインタ | PTR_NEW 関数 |
PTRARR |
||
11 | クラス名 (nullオブジェクトまたはオブジェクトの配列のときOBJREF ) [注2] |
オブジェクト | OBJ_NEW 関数 |
OBJARR |
||
11 | LIST (配列にするとOBJREF ) [注2] |
リスト (IDL8以降) | LIST 関数 |
|||
11 | HASH (配列にするとOBJREF ) [注2] |
ハッシュ (IDL8以降) | HASH関数 |
|||
11 | ORDEREDHASH (配列にするとOBJREF ) [注2] |
順序つきハッシュ (IDL8.3以降) | ORDEREDHASH 関数 |
|||
11 | DICTIONARY (配列にするとOBJREF ) [注2] |
キーの大文字・小文字を区別しないハッシュ (IDL8.3以降) | DICTIONARY関数 |
|||
11 | BIGINTEGER (配列にするとOBJREF ) [注2] |
多倍長整数 (IDL8.4以降) | a = BigInteger(100) または a = BigInteger('123456789012345678980') |
BigInteger |
||
12 | UINT |
16bit符号なし整数 | 0~65535 | a = 1U , a = 1US [注3] |
UINT |
UINTARR |
13 | ULONG |
32bit符号なし整数 | 0~232-1 | a = 1UL |
ULONG |
ULONARR |
14 | LONG64 |
64bit符号付き整数 | -263~263-1 | a = 1LL |
LONG64 |
LON64ARR |
15 | ULONG64 |
64bit符号なし整数 | 0~264-1 | a = 1ULL |
ULONG64 |
ULON64ARR |
SIZE(/TNAME)
は配列であるかどうかにかかわらず常に STRUCT
を返す。SIZE(/TNAME)
は配列であるかどうかにかかわらず常に OBJREF
を返す。COMPILE_OPT IDL2
または COMPILE_OPT DEFINT32
を指定している場合、デフォルトの整数型は32bit整数(LONG
)型となるため、16bit整数型を必要とする場合には明示的に型suffixを付加する必要がある。COMPILE_OPT IDL3
または COMPILE_OPT FLOAT64
を指定している場合、デフォルトの実数型は64bit DOUBLE
型となるため、32bit FLOAT
を必要とする場合には明示的に型suffixを付加する必要がある。i
またはj
で虚数を表記できる。a の型を調べるにはSIZE関数を使う。/TYPE キーワードを指定すると Type Codeを、/TNAMEキーワードを指定するとType Nameを返す。IDL 8.0 以降では TYPENAME関数も使える。構造体やオブジェクトの場合、SIZE(/TNAME)とTYPENAMEの結果が異なる場合があるのに注意。IDL 8.4 以降ではVariable Attributesも使える。
IDL> a = 1ULL
IDL> PRINT, SIZE(a, /TYPE)
15
IDL> PRINT, a.typecode ; IDL 8.4以降
15
IDL> PRINT, SIZE(a, /TNAME)
ULONG64
IDL> PRINT, TYPENAME(a) ; IDL 8.0 以降
ULONG64
IDL> PRINT, a.typename ; IDL 8.4 以降
ULONG64
IDL 8.0 で、データ型を判定するISA関数が追加された。以下、ISA関数を使う場合と、従来の方法を併記する。
変数 a がFLOAT型であるかどうかを判定する。
IDL> a = 1.0
IDL> PRINT, ISA(a, 'FLOAT')
1
IDL> PRINT, SIZE(a, /TNAME) eq 'FLOAT'
1
変数 a が数値(整数、小数、複素数)であるかどうかを判定する。
IDL> a = 1
IDL> PRINT, ISA(a, /NUMBER)
1
IDL> PRINT, ([0b, 1b, 1b, 1b, 1b, 1b, 1b, 0b, 1b, 1b, 0b, 0b, 1b, 1b, 1b, 1b])[SIZE(a, /TYPE)]
1
変数 a が配列(長さ1の配列も配列である)であるかどうかを判定する。(これとは逆の /SCALAR キーワードもある)
IDL> a = [1, 2, 3]
IDL> PRINT, ISA(a, /ARRAY)
1
IDL> PRINT, SIZE(a, /DIMENSIONS) NE 0
1
IDL> PRINT, a.ndim NE 0 ; IDL 8.4 以降
1
数値・文字列型間で相互に型変換する関数が用意されている(上の表の型変換関数の列)。たとえば、FLOAT関数は、他のデータ型の値をFLOAT型に変換する。FIX関数だけは特別で、TYPEキーワードでType Codeを指定することにより、1つの関数で任意の型に変換できる。IDL 8.4以降では IDL_Variable::Convert メソッドを用いることもできる。これらの変換関数は、スカラー変数だけではなく配列にも対応している。
IDL> HELP, FLOAT(1)
<Expression> FLOAT = 1.00000
IDL> HELP, FIX(1, TYPE = 4)
<Expression> FLOAT = 1.00000
IDL> HELP, UINT(3.5)
<Expression> UINT = 3
IDL> HELP, FIX(3.5, TYPE = 12)
<Expression> UINT = 3
IDL> HELP, (1).Convert(/FLOAT) ; IDL 8.4 以降
<Expression> FLOAT = 1.00000
複素数から実数への変換を行うと、実部のみになる。
IDL> HELP, COMPLEX(1, 2)
<Expression> COMPLEX = ( 1.00000, 2.00000)
IDL> HELP, FLOAT(COMPLEX(1, 2))
<Expression> FLOAT = 1.00000
複素数から実部のみを取り出す関数 REAL_PART
、虚部のみを取り出す関数 IMAGINARY
もあり、こちらを使うと単精度/倍精度は保存される。
STRING関数で数値から文字列へ変換する場合、デフォルトでは元の型の最大桁数に対応した桁数が確保されるため、先頭に空白がつく。出力の書式を変更するにはFORMATキーワードを指定する。
IDL> HELP, STRING(3)
<Expression> STRING = ' 3.14000'
IDL> ; IDL 8.6以降ではC言語風のフォーマット指定子も利用できる
IDL> HELP, STRING(3.14, FORMAT='%10.3e')
<Expression> STRING = ' 3.140e+00'
IDL> ; %gを用いると、小数点以下の余分な0が省略される
IDL> HELP, STRING(3.14, FORMAT='%g')
<Expression> STRING = '3.14'
IDL> ; 以下、従来のFORTRAN風のフォーマット指定子
IDL> HELP, STRING(3, FORMAT='(i3)')
<Expression> STRING = ' 3'
IDL> HELP, STRING(3, FORMAT='(i0)')
<Expression> STRING = '3'
IDL> HELP, STRING(3, FORMAT='(i03)')
<Expression> STRING = '003'
IDL> HELP, STRING(3.14, FORMAT='(f)')
<Expression> STRING = ' 3.1400001'
IDL> HELP, STRING(3.14, FORMAT='(f10.3)')
<Expression> STRING = ' 3.140'
IDL> HELP, STRING(3.14, FORMAT='(f0.3)')
<Expression> STRING = '3.140'
IDL> HELP, STRING(3.14, FORMAT='(e)')
<Expression> STRING = ' 3.1400001e+00'
IDL> HELP, STRING(3.14, FORMAT='(e10.3)')
<Expression> STRING = ' 3.140e+00'
文字列から数値への変換も可能である。文字列の先頭から、数値として解釈できる範囲で数値に変換する。数値として解釈不能な場合は、Warningが出力され0が返る。このWarningをプログラムで検出したい場合はON_IOERRORプロシージャを使う。
IDL> HELP, FLOAT('1.5e-5')
<Expression> FLOAT =1.50000e-05
IDL> HELP, FLOAT('1.5e-5ABCDEFG')
<Expression> FLOAT = 1.50000e-05
IDL> HELP, FLOAT('ABCDEFG1.5e-5')
% Type conversion error: Unable to convert given STRING to Float.
% Detected at: $MAIN$
<Expression> FLOAT = 0.00000
BYTE型と文字列の相互変換については特別な処理が行われるので注意が必要である。STRING関数でBYTE型の数値を文字列に変換する場合、数値はASCIIコードだとみなされ、対応する文字に置き換わる。これを防ぐには /PRINT キーワードを指定するか、FORMATキーワードで書式を指定する。またはINTEGER型等の他の型に一旦変換してからSTRINGに渡す。
IDL> HELP, STRING(97B)
<Expression> STRING = 'a'
IDL> HELP, STRING(97B, /PRINT)
<Expression> STRING = ' 97'
1次元のBYTE型の配列は文字列に、2次元のBYTE型の配列は文字列の配列に変換される。
IDL> HELP, STRING([97B, 98B, 99B])
<Expression> STRING = 'abc'
IDL> HELP, STRING(BINDGEN(2, 2) + 65B)
<Expression> STRING = Array[2]
IDL> PRINT, STRING(BINDGEN(2, 2) + 65B)
AB CD
BYTE関数(またはFIX(TYPE=1)関数)で文字列をBYTE型に変換する場合も、ASCIIコードが返される。単純に文字列表記に対応する数値に変換する場合は、FIX関数にTYPE = 1 と /PRINT キーワードをつける。
IDL> HELP, BYTE('123')
<Expression> BYTE = Array[3]
IDL> PRINT, BYTE('123')
49 50 51
IDL> HELP, FIX('123', TYPE = 1, /PRINT)
<Expression> BYTE = 123
数値型の型変換関数は、変換先の型のサイズが変換元より小さいとき、デフォルトでは変換元の下位ビットを返すが、2番目の引数でオフセットを指定することで上位ビットを返すこともできる。剰余やビット演算をしなくても、上位ビットのデータを切り出すことができる。次の例では、24bitカラーをRGBに分解している。
IDL> color = 'FF8040'x
IDL> PRINT, FORMAT='(Z0)', BYTE(color, 2)
FF
IDL> PRINT, FORMAT='(Z0)', BYTE(color, 1)
80
IDL> PRINT, FORMAT='(Z0)', BYTE(color, 0)
40
IDL> PRINT, FORMAT='(Z0)', BYTE(color, 0, 3)
40
80
FF
数値型の型変換関数は、3番目以降の引数で、関数が返す結果の次元を指定できる。結果の次元を指定した場合、入力データの型と次元は無視され単なるバイト列として取り扱われる。つまり、バイト列の内容を変化させることなく、データ型を変換できる。
IDL> a = BINDGEN(16)
IDL> PRINT, FORMAT='(16(Z02," "))', a
00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F
IDL> PRINT, FORMAT='(8(Z04," "))', FIX(a, 0, 8)
0100 0302 0504 0706 0908 0B0A 0D0C 0F0E
IDL> PRINT, FORMAT='(4(Z08," "))', LONG(a, 0, 4)
03020100 07060504 0B0A0908 0F0E0D0C