0

私はこのコードを持っています:

close, 1 & openr,1,filename,error=err
if (err ne 0) then begin
   close, 1
   n=0
   return
endif

line=fltarr(41)

while(not(eof(1))) do begin
   readf,1,line
endwhile

そしてreadf,1,line、次のエラーが表示されます。

READF: End of file encountered. Unit: 1, File: results
Program caused arithmetic error: Floating illegal operand

原因がわかり、それに関するドキュメントを読みましたが、どの算術エラーが EOF と関係があるのか​​ (なぜ EOF なのか? かどうかを確認not(eof(1))しました)、このエラーを取り除くために何をすべきかをまだ理解していません。あなたはなにか考えはありますか?

4

2 に答える 2

1

不正な浮動小数点演算は、おそらくコードの別の部分からのものではなく、コードの別の部分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を返す必要があり、そのビットごとの反転は論理反転と同じであるため、問題になる可能性はほとんどありません。それでも、どのデバッグを試すかは別のことです。1B0B

最後に、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
于 2013-10-18T01:19:21.623 に答える
0

おそらく、ファイルに偶数の 41 個の float が含まれていないでしょう。を呼び出すたびにreadf, 1, line、 を満たすのに十分なデータを読み込もうとしますline。の代わりに、float のサイズをeof()使用fstat()して、1 行を読み取るのに十分なデータがファイルにあるかどうかを判断できます。

于 2013-09-11T12:34:44.213 に答える