开发者

Can you set a maximum limit to an integer (C++)?

If I never want an开发者_运维问答 integer to go over 100, is there any simple way to make sure that the integer never exceeds 100, regardless of how much the user adds to it?

For example,

50 + 40 = 90
50 + 50 = 100
50 + 60 = 100
50 + 90 = 100


Try this:

std::min(50 + 40, 100);
std::min(50 + 50, 100);
std::min(50 + 60, 100);
std::min(50 + 90, 100);

http://www.cplusplus.com/reference/algorithm/min/

Another option would be to use this after each operation:

if (answer > 100) answer = 100;


Here is a fairly simple and fairly complete example of a simple ADT for a generic BoundedInt.

  • It uses boost/operators to avoid writing tedious (const, non-assigning) overloads.
  • The implicit conversions make it interoperable.
  • I shunned the smart optimizations (the code therefore stayed easier to adapt to e.g. a modulo version, or a version that has a lower bound as well)
  • I also shunned the direct templated overloads to convert/operate on mixed instantiations (e.g. compare a BoundedInt to a BoundedInt) for the same reason: you can probably rely on the compiler optimizing it to the same effect anyway

Notes:

  • you need c++0x support to allow the default value for Max to take effect (constexpr support); Not needed as long as you specify Max manually

A very simple demonstration follows.

#include <limits>
#include <iostream>
#include <boost/operators.hpp>

template <
    typename Int=unsigned int, 
    Int Max=std::numeric_limits<Int>::max()>
struct BoundedInt : boost::operators<BoundedInt<Int, Max> >
{
    BoundedInt(const Int& value) : _value(value) {}

    Int get() const { return std::min(Max, _value); }
    operator Int() const { return get(); }

    friend std::ostream& operator<<(std::ostream& os, const BoundedInt& bi)
    { return std::cout << bi.get() << " [hidden: " << bi._value << "]"; }

    bool operator<(const BoundedInt& x) const   { return get()<x.get(); }
    bool operator==(const BoundedInt& x) const  { return get()==x.get(); }
    BoundedInt& operator+=(const BoundedInt& x) { _value = get() + x.get(); return *this; }
    BoundedInt& operator-=(const BoundedInt& x) { _value = get() - x.get(); return *this; }
    BoundedInt& operator*=(const BoundedInt& x) { _value = get() * x.get(); return *this; }
    BoundedInt& operator/=(const BoundedInt& x) { _value = get() / x.get(); return *this; }
    BoundedInt& operator%=(const BoundedInt& x) { _value = get() % x.get(); return *this; }
    BoundedInt& operator|=(const BoundedInt& x) { _value = get() | x.get(); return *this; }
    BoundedInt& operator&=(const BoundedInt& x) { _value = get() & x.get(); return *this; }
    BoundedInt& operator^=(const BoundedInt& x) { _value = get() ^ x.get(); return *this; }
    BoundedInt& operator++() { _value = get()+1; return *this; }
    BoundedInt& operator--() { _value = get()-1; return *this; }
  private:
    Int _value;
};

Sample usage:

typedef BoundedInt<unsigned int, 100> max100;

int main()
{
    max100 i = 1;

    std::cout << (i *= 10) << std::endl;
    std::cout << (i *= 6 ) << std::endl;
    std::cout << (i *= 2 ) << std::endl;
    std::cout << (i -= 40) << std::endl;
    std::cout << (i += 1 ) << std::endl;
}

Demo output:

10 [hidden: 10]
60 [hidden: 60]
100 [hidden: 120]
60 [hidden: 60]
61 [hidden: 61]

Bonus material:

With a fully c++11 compliant compiler, you could even define a Userdefined Literal conversion:

typedef BoundedInt<unsigned int, 100> max100;

static max100 operator ""_b(unsigned int i) 
{ 
     return max100(unsigned int i); 
}

So that you could write

max100 x = 123_b;        // 100
int    y = 2_b*60 - 30;  //  70


Yes.

As a bare minimum, you could start with this:

template <int T>
class BoundedInt
{
public:
  explicit BoundedInt(int startValue = 0) : m_value(startValue) {}
  operator int() { return m_value; }

  BoundedInt operator+(int rhs)
    { return BoundedInt(std::min((int)BoundedInt(m_value + rhs), T)); }

private:
  int m_value;
};


You can write your own class IntegerRange that includes overloaded operator+, operator-, etc. For an example of operator overloading, see the complex class here.


The simplest way would be to make a class that holds the value, rather than using an integer variable.

class LimitedInt
{
    int value;
public:
    LimitedInt() : value(0) {}
    LimitedInt(int i) : value(i) { if (value > 100) value = 100; }
    operator int() const { return value; }
    LimitedInt & operator=(int i) { value = i; if (value > 100) value = 100; return *this; }
};

You might get into trouble with results not matching expectations. What should the result of this be, 70 or 90?

LimitedInt q = 2*60 - 30;


C++ does not allow overriding (re-defining) operators on primitive types.

If making a custom integer class (as suggested above) does not fall under your definition of a "simple way", then the answer to your question is no, there is no simple way to do what you want.


I know it's an old post but I think it could still be usefull for some people. I use this to set upper and lower bound:

bounded_value = max(min(your_value,upper_bound),lower_bound);

You could use it in a function like this:

float bounded_value(float x, float upper, float under){
    return max(min(x,upper),lower);
}
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜