rpinterpreter_doc_floatingPointErrors.txt Copyright (c) Menno Rubingh 2016. Web: [http://rubinghsoftware.de] MR Mar 2016. Handling of FLOATING-POINT ERRORS in this RPInterpreter implementation ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 1) How floating-point errors are handled internally. This implementation internally does NO checking for floating-point errors at the point where the math operations are executed during the evaluation of an expression. Rationale: to maximize processing speed of RPInterpreter::evaluate(). Instead, this implementation uses the "native" handling of floating point errors, which is to set the result to 0 on underflow; +- HUGE_VAL on overflow, and on pole error (division by zero); NaN on domain error. On under/overflow and divbyzero in a math operation, this implementation simply uses the 0 and +-HUGE_VAL result and continues the calculation chain with this value. All math operations correctly handle +-HUGE_VAL as an input (e.g. 1.0/HUGE_VAL poduces zero), and the output variables are simply set to these values. It is OK that output variables are set to +-HUGE_VAL (after an overflow or divbyzero), because the values +-HUGE_VAL are correctly processed by a function double clip( double iVal ) { if ( iVal < MYMIN ) { return MYMIN; } if ( iVal > MYMAX ) { return MYMAX; } return iVal; } in the client code (where MYMIN and MYMAX are any finite double numbers). The only serious error, i.e. the only error that needs to be checked for most applications, is therefore the DOMAIN ERROR (see below). 2) How we check for a DOMAIN ERROR. A DOMAIN ERROR means that a math operation was executed on operand values that lie outside the intervals for with the operation is defined, such as such as raising a negative number to a negative noninteger power. (By the way, note that dividing zero by zero is a domain error, not a pole error). Occurrence of a DOMAIN ERROR occurring anywhere during the evaluation of a single expression, or during a series of evaluation of expressions, can be checked in two ways: 1) By using feclearexcept() and fetestexcept(FE_INVALID) before and after a chain of math operations. This detects any occurrence of a domain error anywhere in the chain. 2) By calling isnan() on the double result of a chain of math operations, to test whether the number is a NaN. Any domain error produces a NaN result, and any math operation with a NaN input produces a NaN output. So the occurrence of a domain error anywhere in the chain of math operations leading to the result number can be checked by testing whether the result number is a NaN. This implementation uses method 2. In this implementation of RPInterpreter, the check for a NaN result value is made at the point where a variable is passed from interpreter to client, that is in the function RPInterpreter::getVar(). This function returns false when the value of the variable is a NaN, and true if it is not a NaN.