The detection of math errors, such as division by zero, overflow, and attempting to take the logarithm of a negative number, is hardware and operating system dependent. Some systems trap more errors than other systems. On systems that implement the IEEE floating-point standard, IDL substitutes the special floating-point values NaN and Infinity when it detects a floating point math error. (See Special Floating-Point Values.) Integer overflow and underflow is not detected. Integer divide by zero is detected on all platforms.

A Note on Floating-Point Underflow Errors

Floating-point underflow errors occur when a non-zero result is so close to zero that it cannot be expressed as a normalized floating-point number. In the vast majority of cases, floating-point underflow errors are harmless and can be ignored.

Accumulated Math Error Status


IDL handles math errors by keeping an accumulated math error status. This status, which is implemented as a longword, contains a bit for each type of math error that is detected by the hardware. When IDL automatically checks and clears this indicator depends on the value of the system variable !EXCEPT. The CHECK_MATH function also allows you to check and clear the accumulated math error status when desired.

!EXCEPT has three possible values:

!EXCEPT=0

Do not report exceptions.

!EXCEPT=1

The default. Report exceptions when the IDL interpreter returns to an interactive prompt. Any math errors that occurred since the last interactive prompt (or call to CHECK_MATH) are printed in the IDL command log. A typical message looks like:

% Program caused arithmetic error: Floating divide by 0

!EXCEPT=2

Report exceptions after each IDL statement is executed. This setting also allows IDL to report on the program context in which the error occurred, along with the line number in the procedure. A typical message looks like:

% Program caused arithmetic error: Floating divide by 0
% Detected at  JUNK                3 junk.pro

Special Floating-Point Values


Machines which implement the IEEE standard for binary floating-point arithmetic have two special values for undefined results: NaN (Not A Number) and Infinity. Infinity results when a result is larger than the largest representation. NaN is the result of an undefined computation such as zero divided by zero, taking the square-root of a negative number, or the logarithm of a non-positive number. In many cases, when IDL encounters the value NaN in a data set, it treats it as “missing data.” The special values NaN and Infinity are also accessible in the read-only system variable !VALUES. These special operands propagate throughout the evaluation process—the result of any term involving these operands is one of these two special values.

Note: For the minimum (<) and maximum (>) operators with NaN operands, the result is undefined and may not necessarily be the special value NaN.

For example:

; Multiply NaN by 3
PRINT, 3 * !VALUES.F_NAN

IDL prints:

NaN

It is important to remember that the value NaN is literally not a number, and as such cannot be compared with a number. For example, suppose you have an array that contains the value NaN:

A = [1.0, 2.0, !VALUES.F_NAN, 3.0]
PRINT, A

IDL prints:

1.00000     2.00000     NaN     3.0000

If you try to select elements of this array by comparing them with a number (using the WHERE function, for example), IDL might generate an error (depending on the hardware and operating system):

; Print the indices of A that are not equal to 1
PRINT, WHERE( A NE 1.0 )

IDL prints:

1     2     3
% Program caused arithmetic error: Floating illegal operand

(Depending on your hardware and operating system, you may not see the floating-point error.)

To avoid this problem, use the FINITE function to make sure arguments to be compared are in fact valid floating-point numbers:

PRINT, WHERE( FINITE(A) ) 

IDL prints the indices of the finite elements of A:

0     1     3

To then print the indices of the elements of A that are both finite and not equal to 1.0, you could use the command:

good = WHERE( FINITE(A) )
PRINT, good[WHERE(A[good] NE 1.0)]

IDL prints:

1     3

Similarly, to find out which elements of an array were not valid floating-point numbers, use a command like:

; Print the indices of the elements of A that are not valid 
; floating-point numbers.
PRINT, WHERE( ~FINITE(A) )

IDL prints:

2

Note that the special value Infinity can be compared to a floating point number. Thus, if:

B = [1.0, 2.0, !VALUES.F_INFINITY]
PRINT, B

IDL prints:

1.00000      2.00000          Inf

and

PRINT, WHERE(B GT 1.0)

IDL prints:

1           2

You can also compare numbers directly with the special value Infinity:

PRINT, WHERE(B EQ !VALUES.F_INFINITY)

IDL prints:

2

Note: On Windows, using relational operators such as EQ and NE with the values infinity or NaN (Not a Number) causes an “illegal operand” error. The FINITE function’s INFINITY and NAN keywords can be used to perform comparisons involving infinity and NaN values. For more information, see FINITE.

The FINITE Function


Use the FINITE function to explicitly check the validity of floating-point or double-precision operands on machines which use the IEEE floating-point standard. For example, to check the result of the EXP function for validity, use the following statement:

;Perform exponentiation.
A = EXP(EXPRESSION)
 
;Print error message.
IF ~ FINITE(A) THEN PRINT, 'Overflow occurred'

If A is an array, use the statement:

IF TOTAL(FINITE(A)) NE N_ELEMENTS(A) THEN

Integer Conversions


It must be stressed that when converting from floating to any of the integer types (byte, signed or unsigned short integer, signed or unsigned longword integer, or signed or unsigned 64-bit integer) if overflow is important, you must explicitly check to be sure the operands are in range. Conversions to the above types from floating point, double precision, complex, and string types do not check for overflow—they convert the operand to the target integer type, discarding any significant bits of information that do not fit.

When run on a Sun workstation, the program:

A = 2.0 ^ 31 + 2
PRINT, LONG(A), LONG(-A), FIX(A), FIX(-A), BYTE(A), BYTE(-A)

(which creates a floating-point number 2 larger than the largest positive longword integer), prints the following:

2147483647 -2147483648 -1 0 255 0
% Program caused arithmetic error: Floating illegal operand

This result is incorrect.

Note: No error message will appear if you attempt to convert a floating number whose absolute value is between 215 and 231 - 1 to short integer even though the result is incorrect. Similarly, converting a number in the range of 256 to 231 - 1 from floating, complex, or double to byte type produces an incorrect result, but no error message. Furthermore, integer overflow is usually not detected. Your programs must guard explicitly against it.