c++comparisonbig-omagnitude

More general test for same order of magnitude than comparing floor(log10(abs(n)))


I am implementing an optimization algorithm and have diferent heuristics for cases where no or largely different lower and upper bounds for the solution are known or not.

To check, my first approach would be simply taking

if(abs(floor(log10(abs(LBD))) - floor(log10(abs(UBD)))) < 1 )
{ //(<1 e.g. for 6, 13)
  //Bounds are sufficiently close for the serious stuff 
}
else {
  //We need some more black magic
}

But this requires previous checks to be gerneralized to NAN, ±INFINITY. Also, in the case where LBD is negative and UBD positive we can't assume that the above check alone assures us that they are anywhere close to being of equal order of magnitude.

Is there a dedicated approach to this or am I stuck with this hackery?


Solution

  • Thanks to geza I realized that thw whole thing can be done without the log10: A working solution is posted below, and a MWE including the log variant posted on ideone.

    template <typename T> double sgn(T val) {
        return double((T(0) < val) - (val < T(0)))/(val == val);
    }
    bool closeEnough(double LBD, double UBD, uint maxOrderDiff = 1, uint cutoffOrder = 1) {
      double sgn_LBD = sgn(LBD);
      double sgn_UBD = sgn(UBD);
      double cutoff = pow(10, cutoffOrder);
      double maxDiff = pow(10, maxOrderDiff);
      if(sgn_LBD == sgn_UBD) {
         if(abs(LBD)<cutoff && abs(UBD)<cutoff) return true;
         return LBD<UBD && abs(UBD)<abs(LBD)*maxDiff;
      }
      else if(sgn_UBD > 0) {
        return -LBD<cutoff && UBD<cutoff;
      }
      // if none of the above matches LBD >= UBD or any of the two is NAN
    }
    

    As a bonus it can take cutoffs, so if both bounds lie within [-10^cutoffOrder,+10^cutoffOrder] they are considered to be close enough! The pow computation might also be unecessary, but at least in my case this check is not in a critical code section. If it would be, I suppose you could just hard code the cutoff and maxDiff.