Erik
Erik

Reputation: 131

How can i make two values constrain each other consistently?

I have two variables, static int16_t min and static int16_t max.

I want them to constrain each other, so that

Also, each value needs to be restricted within the value range of 0 - 15 (The variables are declared as int16_t since they're used for several purposes, besides the range in this particular instance).

I tried the following code:

min = constrain(min, 0, max);
max = constrain(max, min, 15);

This works as intended for min's value, meaning: once min is increased up to max it won't increase beyond the value of max. On the other hand, when the value of max is decreased to a value equal to min, it keeps reducing both values until they're both down to 0.

I have a hard time figuring out how the logic can be solved, and would appreciate any advice that makes the logic consistent for both values, so in other words I'd be fine with a solution that either makes:

Upvotes: 1

Views: 383

Answers (1)

463035818_is_not_an_ai
463035818_is_not_an_ai

Reputation: 123149

Short answer: Encapsulation.

What you describe is an invariant. Invariants are guaranteed by user defined data types by encapsulating the private data and only provide the user access to methods that have the invariant as post condition.

Only to outline the idea:

class min_max {
    int min;
    int max;
    void normalize_min() {  if (min > max) min = max; }
    void normalize_max() {  if (max < min) max = min; }

public:
    min_max(int a,int b) : min(std::min(a,b)), max(std::max(a,b)) {}
    void set_min(int x) {
       min = x;
       normalize_max();
    }
    void set_max(int x) {
       max = x;
       normalize_min();
    }
    int get_max() { return max; }
    int get_min() { return min; }
};

From outside the class there is no way to reach a situation where max < min.

Consider the comment by Yakk on your question. I wasn't sure what you actually want and for the above I assumed after calling mm.set_max(a) we can assert that mm.get_max() == a and only min is adjusted (vice versa for set_min). Other solutions are possible, for example you could throw an exception when the user attempts to set a max that is larger than min, or signal an error in a different way.

Upvotes: 2

Related Questions