不正な浮動小数点演算は、おそらくコードの別の部分からのものではなく、コードの別の部分not(eof(1))
からのものreadf, 1, line
か、持ち越されたものです。
IDL は 41 個の 32 ビット浮動小数点値を読み取ることを想定していますが、読み取った値の一部またはすべてが有効な浮動小数点数ではありません。1 と 0 の 32 ビット系列のすべてが有効な IEEE float32 (IDL および他のほとんどの言語で使用される「float」値) になるわけではありません。うっかりファイルの終わりに遭遇した場合、ファイルから読み取られたデータの一部が float32 にうまく収まらない可能性が高くなります。その場合、IDL は、データがどの浮動小数点数になるべきかについて情報に基づいた推測を試みますが、これは技術的には IEEE 標準の一部ではないため、Program caused arithmetic error: Floating illegal operand
エラーが発生します。
調査するには、次のコードに置き換えてみてください。
close, 1 & openr, 1, filename, error=err
if (err ne 0) then begin
close, 1
n = 0
return
endif
line = bytarr(41 * 4)
while not(eof(1)) do begin
readf, 1, line
endwhile
この場合、float 配列ではなく byte 配列に読み込んでいるため、唯一のエラーはREADF: End of file encountered. Unit: 1, File: results
.
もう 1 つの考えられる問題は、not(eof(1))
非標準の の使用です。IDL ではnot
、ビット単位の not です。つまり、次の項のすべてのビットを反転します。ここでのより適切な演算子は、「論理否定」~
です。not(eof(1))
したがって、またはの代わりに、 のnot eof(1)
使用を検討して~eof(1)
ください。この特定のケースでは、または のいずれかeof
を返す必要があり、そのビットごとの反転は論理反転と同じであるため、問題になる可能性はほとんどありません。それでも、どのデバッグを試すかは別のことです。1B
0B
最後に、Floating illegal operand
エラーが実際にはエラーの前READF: End of file encountered
に発生している可能性があります。これは直感的ではありませんが、次のコード ブロックを検討してください。
x = sqrt(-1.0)
print, 'Hello, World.'
これは以下を出力します:
Hello, World.
% Program caused arithmetic error: Floating illegal operand
浮動小数点不正オペランド エラーの前Hello, World.
に出力されたことに注意してください。これは、関数が戻るか、プログラムが終了/クラッシュするか、関数が呼び出されるまで、IDL が実際に浮動小数点エラーを報告しないためです。プログラムがこのブロックの前に浮動小数点エラーを生成しているかどうかを確認するには、コード ブロックの先頭に配置します。そうすることで 0 以外の値が出力される場合は、ブロックの前に浮動小数点エラーが発生しています。を使用すると、これらのエラー状態もリセットされるため、浮動小数点エラーを引き起こす可能性のある各ステートメントの後に置くことで、浮動小数点エラー メッセージを抑制することができます。check_math()
print, check_math()
check_math()
math_err = check_math()
上記のすべてのエラーを処理できる元のコードの修正版を次に示します。
math_err = check_math() ; remove any lingering floating point errors
close, 1
openr, 1, filename, error=err
if err ne 0 then begin
close, 1
n = 0
return
endif
line = fltarr(41)
catch, err ; return here if a non-math error happens
if err ne 0 then begin
catch, /cancel ; prevent infinite loop between catch and message
if !error_state.name eq 'IDL_M_FILE_EOF' then begin
; Handle premature end-of-file here.
endif else begin
message, /reissue_last ; issue non-eof errors normally
endelse
endif else begin
while ~eof(1) do begin
readf, 1, line
; Handle new line here.
endwhile
catch, /cancel ; stop error checking
endelse