From vitali at upb.de Wed Nov 20 04:14:34 2019 From: vitali at upb.de (Vitali Gintner) Date: Wed, 20 Nov 2019 09:14:34 -0000 Subject: [CoinUtils] floating-point exceptions Message-ID: <0dc601d59f82$5ce31b10$16a95130$@upb.de> 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 #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 (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 (floor(upperValue+1.0e-5)); } int iLower = -COIN_INT_MAX; // check for -COIN_DBL_MAX if (lowerValue > -COIN_DBL_MAX) { iLower = static_cast (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: