Можете ли вы установить максимальный предел целому числу (C ++)? - PullRequest
4 голосов
/ 01 октября 2011

Если я не хочу, чтобы целое число превышало 100, есть ли простой способ убедиться, что целое число никогда не превышает 100, независимо от того, сколько пользователь добавляет к нему?

Например,

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

Заранее спасибо

Ответы [ 7 ]

11 голосов
/ 01 октября 2011

Попробуйте:

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/

Другой вариант будет использовать это после каждой операции:

if (answer > 100) answer = 100;
6 голосов
/ 01 октября 2011

Вот довольно простой и довольно полный пример простого ADT для общего BoundedInt.

  • В нем используются операторы boost /, чтобы избежать утомительных (постоянных, неназначающих) перегрузок.
  • Неявные преобразования делают его совместимым.
  • Я избегал интеллектуальных оптимизаций (поэтому код легче адаптировался, например, к версии по модулю или к версии, которая также имеет нижнюю границу)
  • Я также избегал прямых шаблонных перегрузок для преобразования / работы со смешанными экземплярами (например, сравниваем BoundedInt с BoundedInt) по той же причине: вы, вероятно, можете полагаться на то, что компилятор оптимизирует его до того же эффекта в любом случае

Примечания:

  • вам нужна поддержка c ++ 0x, чтобы значение по умолчанию для Max вступило в силу (поддержка constexpr ); Не требуется, если вы указали Макс вручную

Далее следует очень простая демонстрация.

#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;
};

Пример использования:

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;
}

Демонстрационный вывод:

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

Бонусный материал:

С полностью совместимым с ++ 11 компилятором вы даже можете определить определяемое пользователем литералом преобразование:

typedef BoundedInt<unsigned int, 100> max100;

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

Чтобы вы могли написать

max100 x = 123_b;        // 100
int    y = 2_b*60 - 30;  //  70
1 голос
/ 01 октября 2011

Да.

Как минимум, вы можете начать с 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;
};
0 голосов
/ 24 сентября 2014

Я знаю, что это старый пост, но я думаю, что он все еще может быть полезен для некоторых людей. Я использую это для установки верхней и нижней границы:

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

Вы можете использовать его в такой функции:

float bounded_value(float x, float upper, float under){
    return max(min(x,upper),lower);
}
0 голосов
/ 01 октября 2011

C ++ не позволяет переопределять (переопределять) операторы примитивных типов.

Если создание пользовательского целочисленного класса (как предложено выше) не подпадает под ваше определение «простого пути», то ответ на ваш вопрос нет , простого способа сделать то, что ты хочешь.

0 голосов
/ 01 октября 2011

Самый простой способ - создать класс, содержащий значение, а не использовать целочисленную переменную.

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; }
};

У вас могут возникнуть проблемы с результатами, не соответствующими ожиданиям. Каким должен быть результат, 70 или 90?

LimitedInt q = 2*60 - 30;
0 голосов
/ 01 октября 2011

Вы можете написать свой собственный класс IntegerRange, который включает перегруженные operator+, operator- и т. Д. Пример перегрузки операторов см. В комплексном классе здесь .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...