Search code examples
c++stepper

Creating a stepper control with a limiter


I created a simple stepper control that has a limiter.

It seems to work well in general. But if I try to make the limiter ranges from numeric_limits<float>::min() to numeric_limits<float>::max(), it doesn't work properly when the value becomes negative.

Here's my full test code.

#include <iostream>

using namespace std;

class Stepper {

public:

    Stepper(float from, float to, float value, float interval){ //limited range

        mFrom = from;
        mTo = to;
        mValue = value;
        mInterval = interval;
    }
    Stepper(float value, float interval){ //limitless range version

        mFrom = numeric_limits<float>::min();
        mTo = numeric_limits<float>::max();
        mValue = value;
        mInterval = interval;
    }

    float getCurrentValue() {

        return mValue;
    }
    float getDecreasedValue() {

        if (mFrom < mTo)
            mValue -= mInterval;
        else
            mValue += mInterval;

        mValue = clamp(mValue, min(mFrom, mTo), max(mFrom, mTo));
        return mValue;
    }
    float getIncreasedValue() {

        if (mFrom < mTo)
            mValue += mInterval;
        else
            mValue -= mInterval;

        mValue = clamp(mValue, min(mFrom, mTo), max(mFrom, mTo));
        return mValue;
    }

private:

    float clamp(float value, float min, float max) {
        return value < min ? min : value > max ? max : value;
    }
    float mFrom, mTo, mValue, mInterval;
};

int main(int argc, const char * argv[]) {

    bool shouldQuit = false;

//    Stepper stepper(-3, 3, 0, 1); //this works

    Stepper stepper(0, 1); //this doesn't work when the value becomes negative


    cout << "step : " << stepper.getCurrentValue() << endl;

    while (!shouldQuit) {

        string inputStr;
        cin >> inputStr;

        if (inputStr == "-") //type in '-' decrease the step
            cout << "step : " << stepper.getDecreasedValue() << endl;
        else if (inputStr == "+") //type in '+' increase the step
            cout << "step : " << stepper.getIncreasedValue() << endl;
        else if (inputStr == "quit")
            shouldQuit = true;
    }
    return 0;
}

My class constructor requires 4 arguments that are

  1. minimum limited value (this also can be maximum)
  2. maximum limited value (this also can be minimum)
  3. initial value
  4. interval of steps

Also, the constructor can take only 2 arguments that are

  1. initial value
  2. interval of steps

This case, the limiter ranges from numeric_limits<float>::min() to numeric_limits<float>::max().

But in this case, if the value becomes negative, it returns 1.17549e-38 which is the same value as numeric_limits<float>::min().

Is it possible to fix this? Any advise or guidance would be greatly appreciated!


Solution

  • std::numeric_limits<float>::lowest() is the lowest values in the mathematical sense. std::numeric_limits<float>::min() is only the smallest positive value (greater than zero).

    For details, see this question. The naming goes back to C.