[Cbc] floating-point exceptions

Vitali Gintner vitali at upb.de
Wed Nov 20 04:10:31 EST 2019


Dear coin community,

 

I detected several floating-point exceptions (FLTIV and FLTOV) in coin
sources, components Clp, Cbc, Cgl, and CoinUtils. The exceptions occurred in
some of my tests when checking for it by switching on these kind of
exceptions with system call

 

  feenableexcept(FE_DIVBYZERO | FE_OVERFLOW | FE_INVALID);

 

Works with

#define __USE_GNU 1

#include <fenv.h>

#undef __USE_GNU

 

The listed examples already show a possible fix. It would be great if
someone could look at these issues.

In addition, a general approach of handling floating-point calculations
would be great.

 

Kind regards

Vitali

 

Clp/src/ClpPackedMatrix::scale (around line 3599)

  // first if added to avoid float overflow

  if (difference < 1.0e-4 || rowScale[iRow] < 1.0) {  

    double scaledDifference = difference * rowScale[iRow];

    if (scaledDifference > tolerance && scaledDifference < 1.0e-4) {

      // make gap larger

      rowScale[iRow] *= 1.0e-4 / scaledDifference;

      rowScale[iRow] = CoinMax(1.0e-10, CoinMin(1.0e10, rowScale[iRow]));

   }

  }

Cbc/src/CbcModel::analyzeObjective() (around line 595)

// added largestObj < smallestObj because smallest was already infinity

else if ((largestObj < smallestObj || largestObj < smallestObj*5.0) && 

           !parentModel_ &&

           !numberContinuousObj &&

           !numberGeneralIntegerObj &&

           numberIntegerObj*2 < CoinMin(numberColumns,20)) 

Cbc/src/CbcModel::solveWithCuts() (around line 9354) 

  // added divisor since static_cast<double> (numberActiveGenerators - 1)
was 0

  if (divisor == 0.0)

      divisor = 0.00001;

  smallProblem = (0.2 * (totalCuts - generator_[i]->numberCutsInTotal())) /

                  divisor ;

Cbc/src/CbcHeuristic::CbcRounding::solution (around line 2462)

  // distance was infinity, gap negative -> added gap + distance > 0.0 ||

  if (gap + distance > 0.0 || gap + value*distance > 0.0)

      distance = -gap / value;

Cgl/src/CglPreProcess.cpp::preProcessNonDefault (around line 1722)

  // check for +COIN_DBL_MAX

  if (upperValue < COIN_DBL_MAX) {

    iUpper = static_cast<int> (floor(upperValue+1.0e-5));

  }

  int iLower = -COIN_INT_MAX;

 

  // check for -COIN_DBL_MAX

  if (lowerValue > -COIN_DBL_MAX) {

    iLower = static_cast<int> (ceil(lowerValue-1.0e-5));

  }

Cgl/src/CglTwomir.cpp::DGG_add2stepToList (around line 1782)

  // added if because cut->rhs was 0

  if (cut->rhs > 1E-6 || cut->rhs < -1E-6)

    norm_val /= cut->rhs * cut->rhs;

 

CoinUtils/src/CoinPresolveDual.cpp::remove_dual_action::presolve (around
line 595) 

  // rephrased computation of mindelta and maxdelta

  double mindelta = ymin[i] ;

  if (ymin[i] > -COIN_DBL_MAX || (aij <= 1.0 && aij >= -1.0)){

    mindelta = aij*ymin[i] ;

  }

  double maxdelta = ymax[i] ;

  if (ymax[i] < COIN_DBL_MAX || (aij <= 1.0 && aij >= -1.0)){

    maxdelta = aij*ymax[i] ;

  }

 

 

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://list.coin-or.org/pipermail/cbc/attachments/20191120/0496d467/attachment-0001.html>


More information about the Cbc mailing list