非法浮点运算可能不是来自代码的另一部分,not(eof(1))
而是来自readf, 1, line
或继承自代码的另一部分。
IDL 期望读入 41 个 32 位浮点值,但它读入的部分或全部值不是有效的浮点数。并非所有 32 位系列的 1 和 0 都构成有效的 IEEE float32(IDL 和大多数其他语言中使用的“浮点”值)。如果您无意中遇到文件结尾,则从文件中读取的某些数据很可能无法很好地适合 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
在这种情况下,因为您正在读取字节数组而不是浮点数组,所以唯一的错误应该是READF: End of file encountered. Unit: 1, File: results
.
另一个可能的问题是使用not(eof(1))
,这是非标准的。在 IDL 中,not
是按位不,这意味着它反转下一项的所有位。这里更合适的运算符是“逻辑非”,~
。因此,代替not(eof(1))
or not eof(1)
,考虑使用~eof(1)
. 在这种特殊情况下,这不太重要,因为eof
应该返回1B
or 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