Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Change comparison operators without large conditional block

I am testing whether a number lies between two values. I leave it up to the user to choose whether the logical comparison should include an equal to on either (or both) of the limits or not. They set this by defining a structwhich contains the two edge values and which comparison operator to use:

typedef struct {
    double low; 
    double high;
    bool low_equal; //false if a greater than operator (`>`) should be used, true if a greater-than-or-equal-to (`>=`) operator should be used
    bool high_equal; //Same as low_equal but for a less-than operator
} Edges;

An array of Edges is created, (termed bins below) and for each input value I check whether it lies within the bin edges. However, in order to use the desired pair of comparison operators, I've ended up with this hideous conditional block:

        if (bins[j].low_equal && bins[j].high_equal)
        {
            if (value >= bins[j].low && value <= bins[j].high)
            {
                break;
            }
        }
        else if (bins[j].low_equal)
        {
            if (value >= bins[j].low && value < bins[j].high)
            {
                data[i] = bins[j].value;
                break;
            }
        }
        else if (bins[j].high_equal)
        {
            if (datum > bins[j].low && datum <= bins[j].high)
            {
                break;
            }
        }
        else
        {
            if (value > bins[j].low && value < bins[j].high)
            {
                break;
            }
        }

Is there a better way to do this? Can I somehow set the operators to use and then just call them?

like image 368
jramm Avatar asked Jun 20 '26 10:06

jramm


2 Answers

A simple approach could be:

bool higher = (value > bins[j].low) || (bins[j].low_equal && value == bins[j].low); 
bool lower  = (value < bins[j].high) || (bins[j].high_equal && value == bins[j].high); 

if (higher && lower)
{
    // In range
}
like image 79
Support Ukraine Avatar answered Jun 21 '26 22:06

Support Ukraine


you may use pointer on function

bool less(double lhs, double rhs) { return lhs < rhs; }
bool less_or_equal(double lhs, double rhs) { return lhs <= rhs; }
using comp_double = bool(double, double);

and then

comp_double *low_comp = bins[j].low_equal ? less_or_equal : less;
comp_double *high_comp = bins[j].high_equal ? less_or_equal : less;

if (low_comp(bins[j].low, value) && high_comp(value, bins[j].high)) {
   // In range
}
like image 44
Jarod42 Avatar answered Jun 21 '26 23:06

Jarod42



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!