Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Absolute hysteresis calculation in C++

Tags:

c++

algorithm

I want to implement a template function, which detects if the difference of ValueA and ValueB is bigger than a given hystersis. e.x.

  • ValueA=5, ValueB=7, Hystersis=1 -> true
  • ValueA=5, ValueB=7, Hystersis=3 -> false
  • ValueA=-5, ValueB=1, Hystersis=7 -> false

So I implemented this function:

template<typename T>
bool MyClass::IsHysteresisExceeded(T ValueA, T ValueB, T Hysteresis) {
    T ValueMax = std::max(ValueA, ValueB);
    T ValueMin = std::min(ValueA, ValueB);
    return (ValueMax - ValueMin) > Hysteresis;
}

But with the following parameters this function returns false when I expected true as result.

IsHysteresisExceeded<int>(-2147483648, 2147483647, 10)

I know that a integer overflow occurs while subtracting, but I did not find an elegant solution yet.

like image 546
Sir2B Avatar asked Oct 15 '25 13:10

Sir2B


1 Answers

I have the following solution for integers:

template<typename T>
bool IsHysteresisExceeded(T ValueA, T ValueB, T Hysteresis) {
    T ValueMax = std::max(ValueA, ValueB);
    T ValueMin = std::min(ValueA, ValueB);
    assert(Hysteresis >= 0);
    T underflowRange = std::numeric_limits<T>::min() + Hysteresis;
    bool underflow =  underflowRange > ValueMax;
    return !underflow && (ValueMax - Hysteresis > ValueMin);
}

The trick is to detect the underflow. If it happens you may be sure ValueMin is in range <ValueMax,std::numeric_limits<T>::min()> and

(ValueMax - Hysteresis) < std::numeric_limits<T>::min() <= ValueMin

I posted the code on godbolt.org

Edit: My previous answer used a very popular approach and was also wrong. I proposed to detect the underflow like:

T lowBound = ValueMax - Hysteresis;
bool underflow = lowBound > ValueMax;

Although it produces expected results on the architectures i know, it is an undefined behavior.

like image 156
Bartosz Charuza Avatar answered Oct 18 '25 05:10

Bartosz Charuza



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!