Search code examples
c++logical-operatorscomparison-operators

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?


Solution

  • 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
    }