Незаконната операция с плаваща запетая вероятно не е от not(eof(1))
, а от readf, 1, line
или е пренесена от друга част от кода.
IDL очаква да чете 41 32-битови стойности с плаваща запетая, но някои или всички стойности, които чете, не са валидни числа с плаваща запетая. Не всички 32-битови серии от 1s и 0s правят валиден IEEE float32 (стойностите "float", използвани в 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))
или 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