Недопустимая операция с плавающей запятой, вероятно, не из 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, то есть инвертирует все биты следующего термина. Более подходящим оператором здесь будет «логическое НЕ», ~
. Таким образом, вместо 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 на самом деле не сообщает об ошибках с плавающей запятой до тех пор, пока функция не вернется, программа не завершится/не завершится сбоем или не будет вызвана функция check_math()
. Чтобы проверить, генерирует ли ваша программа ошибку с плавающей запятой перед этим блоком, поместите print, check_math()
в начало блока кода. Если при этом печатается что-либо кроме 0, то перед блоком произошли ошибки с плавающей запятой. Использование 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
person
Pi Marillion
schedule
18.10.2013