Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

Errors during floating-point operations are often neglected by programmers who instead focus on validating operands before an operation. Errors occurring that occur during floating-point operations are admittedly difficult to determine and diagnose, but the benefits of doing so often outweigh the costs. This recommendation suggests ways to capture errors during floating-point operations.

...

  • Conversion from floating-point to integer may cause an "invalid" floating-point exception. If this occurs, the value of that integer is undefined and should not be used.
  • Most implementations fail to raise "invalid" for conversions from any negative or "large" positive floating-point values to unsigned integer types or to signed char. (See tflt2int.c.)
  • When a noninteger floating-point value is converted to an integer, the "inexact" floating-point exception is raised.

...

Code Block
bgColor#ccccff
langc
void fp_usingSEH(void) {
  /* ... */
  double a = 1e-40, b, c = 0.1;
  float x = 0, y;
  unsigned int rv ;

  unmask_fpsr();

  _try {
    /* Store into y is inexact and underflows */
    y = a;

    /* Divide-by-zero operation */
    b = y / x;

    /* Inexact */
    c = sin(30) * a;
  }

  _except (_fpieee_flt(
             GetExceptionCode(),
             GetExceptionInformation(),
             fpieee_handler)) {
  {
  printf ("fpieee_handler: EXCEPTION_EXECUTE_HANDLER");
  }

  /* ... */
}

void unmask_fpsr(void) {
  unsigned int u;
  unsigned int control_word;
  _controlfp_s(&control_word, 0, 0);
  u = control_word & ~(_EM_INVALID
                     | _EM_DENORMAL
                     | _EM_ZERODIVIDE
                     | _EM_OVERFLOW
                     | _EM_UNDERFLOW
                     | _EM_INEXACT);
  _controlfp_s( &control_word, u, _MCW_EM);
  return ;
}

int fpieee_handler(_FPIEEE_RECORD *ieee) {
  /* ... */

  switch (ieee->RoundingMode) {
    case _FpRoundNearest:
      /* ... */
      break;

      /* Other RMs include _FpRoundMinusInfinity,
       * _FpRoundPlusInfinity, _FpRoundChopped */

      /* ... */
    }

  switch (ieee->Precision) {
    case _FpPrecision24:
      /* ... */
      break;

      /* Other Ps include _FpPrecision53 */
      /* ... */
    }

   switch (ieee->Operation) {
     case _FpCodeAdd:
       /* ... */
       break;

       /* Other Ops include _FpCodeSubtract, _FpCodeMultiply,
        * _FpCodeDivide, _FpCodeSquareRoot, _FpCodeCompare,
        * _FpCodeConvert, _FpCodeConvertTrunc */
       /* ... */
    }

  /* 
   * Process the bitmap ieee->Cause.
   * Process the bitmap ieee->Enable.
   * Process the bitmap ieee->Status.
   * Process the Operand ieee->Operand1, 
   * evaluate format and Value.
   * Process the Operand ieee->Operand2, 
   * evaluate format and Value.
   * Process the Result ieee->Result, 
   * evaluate format and Value.
   * The result should be set according to the operation 
   * specified in ieee->Cause and the result formatted as 
   * specified in ieee->Result.
   */

  /* ... */
}

...

Recommendation

Severity

Likelihood

Remediation Cost

Priority

Level

FLP03-C

lowLow

probableProbable

highHigh

P2

L3

Automated Detection

Tool

Version

Checker

Description

Compass/ROSE

 

 

Could detect violations of this rule by ensuring that floating-point operations are surrounded by feclearexcept() and fetestexcept(). It would need to look for type conversions to float or double, divisions (by a number not known to be nonzero), and multiplication. It may be wisest to apply this to all floating-point operations in general

PRQA QA-C
Include Page
PRQA_V
PRQA_V

4123
4124
4125
4126
4127
4128

Partially implemented

...