2

I'm trying to make sure that int x is greater or equal than 0 but smaller than 1080 (screen size in this case).

I came up with this

int x = 123;
x = std::min(std::max(x, 0), 1080);

This seems ugly. Is there a better way to achieve this?

melpomene
  • 84,125
  • 8
  • 85
  • 148
Eric
  • 19,525
  • 19
  • 84
  • 147

4 Answers4

8

If you live in the future, you can use std::clamp from C++17:

x = std::clamp(x, 0, 1080);
melpomene
  • 84,125
  • 8
  • 85
  • 148
2

Naive solution looks ok too:

int x = 123;
if (x < 0)
    x = 0;
if (x > 1080)
    x = 1080;

or wrap everything in a function:

template<typename T>
T between(const T x, const T min, const T max){
   if (x < min)
       return min;

   if (x > max)
       return max;

   return x;
}

int x = between(123, 0, 1080);
Nick
  • 9,962
  • 4
  • 42
  • 80
1

Use an unsigned as the type for x. That automatically constrains it to be non-negative.

Then you're left with just the call to std::min which is palatable to me at least.

Building a class that takes an int on construction and has a conversion operator to int is also plausible but requires a fair bit of boilerplate.

Bathsheba
  • 231,907
  • 34
  • 361
  • 483
  • This is a good idea, but unfortunately x is fetched through an API callback so I can't change the type easily. Of course I could cast int to unsigned int, but this is ugly as well imo – Eric Jan 08 '17 at 17:31
-1

Why not just do something like this?

int x = 123; /* Or some arbitrary number */
bool bIsInRange = (x >= 0) && (x < 1080);
if(!bIsInRange){
   std::cout << "Variable 'x' is not between 0 and 1080." << std::endl;
   return 1;
} // else, x is fine. Continue operations as normal.
Spencer D
  • 3,376
  • 2
  • 27
  • 43
  • That looks super ugly. – melpomene Jan 08 '17 at 17:33
  • @melpomene, however, it is also standard, readable, and extremely understandable for anyone of any experience level. Plus, doing it in this normal way does not require additional calls to functions such as `min`, `max`, or `clamp`, which only serve to add overhead/expense to what would otherwise be a simple and essentially weightless task. That being said, I will agree that it is by no means *"beautiful."* – Spencer D Jan 08 '17 at 17:40
  • I don't find it readable. The main issue is the `bIsInRange` variable, which serves no purpose and has a horrible name. As for overhead, I'd expect the compiler to inline min/max/clamp. (And if we're talking efficiency, that `cout << "..." << endl` construct is probably 100 times slower than a plain function call.) – melpomene Jan 08 '17 at 17:43