#include <iostream>
#include <vector>
#include <cmath>

using namespace std;

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) {
  	 bool test = -LBD<cutoff && UBD<cutoff; 
  	 if(test) return test;
	 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
}


bool closeEnoughLog(double LBD, double UBD) {
  double dist = 42;
  double sgn_LBD = sgn(LBD);
  double sgn_UBD = sgn(UBD);
  if(sgn_LBD == sgn_UBD) {
    if(LBD < UBD) { // central assumption!
      dist = max(log10(abs(UBD)), 0.0) - max(log10(abs(LBD)), 0.0);
      // We take max here because -10 < n < 10 is considered close enough!
    }
  }
  else if(sgn_UBD > 0) { // LBD <= 0
    dist = log10(-LBD) + log10(UBD); // can be negative but that's ok
  }
  // if none of the above matches LBD >= UBD or any of the two is NAN
  return (dist < 1);
}

int main() {
  vector<double> LBD = {-INFINITY,-INFINITY,-100, -0.09, 0.09, NAN, -4, -2.4, 333, -40, -2.33};
  vector<double> UBD = {+INFINITY, NAN,      100, 1,     1,    NAN, 0.02,   2.4,  231, 40, -0.023};
  vector<uint> desired = {0,       0,        0,   1,     1,    0,   1,     1,    0,   0, 1 };
  printf("%7s %7s %3s %6s %5s\n", "LBD", "UBD", "log", "simple", "check");
  for(auto i(0); i < desired.size(); ++i) {
  	printf("%7.2f %7.2f %3d %6d %5d\n", LBD[i], UBD[i], closeEnoughLog(LBD[i], UBD[i]), closeEnough(LBD[i], UBD[i]), desired[i] );
  }
  
  return 0;
}