2013-09-10 8 views
0

У меня есть этот код:арифметическая ошибка: Плавающий нелегальный операнд [IDL]

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))) и что делать, чтобы избавиться от этой ошибки. У тебя есть идеи?

ответ

1

Незаконная операция с плавающей точкой, вероятно, не от not(eof(1)), а от readf, 1, line или переносится с другой части кода.

IDL ожидает чтения в 41 32-битном значении с плавающей запятой, но некоторые или все значения, которые он считывает, не являются действительными числами с плавающей запятой. Не все 32-разрядные серии из 1 и 0 делают допустимым 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 
0

Возможно, у вас нет четного числа 41 поплавка в файле. Каждый звонок readf, 1, line попытается прочитать достаточно данных, чтобы заполнить line. Вместо eof() вы можете использовать fstat() и размер поплавка, чтобы определить, достаточно ли данных в файле для чтения строки.

Смежные вопросы