Cómo establecer un límite máximo y mínimo para una variable entera / flotante en la definición

Esto se volvió interesante cuando comencé a pensar en soluciones. Podría llegar a 3 que pueden ayudarte. De hecho, algunos de ellos pueden ser tontos, pero pueden ayudarte de alguna manera.

Aquí está el más común: usar límites numéricos superior e inferior

// intento 1
plantilla
clase Verified_numeral {
_typ safe_numeral;
público:
check_numeral () {
safe_numeral = static_cast (_lower_bound);
}

check_numeral (_typ _val) {
_check (_val);
safe_numeral = _val;
}

static bool is_within_bounds (const _typ & _val) {

int _real_upper_bound = _upper_bound <_lower_bound? _lower_bound: _upper_bound;
int _real_lower_bound = _lower_bound> _upper_bound? _upper_bound: _lower_bound;

return (_val <= static_cast (_real_upper_bound)
&& _val> = static_cast (_real_lower_bound));
}

_typ operator = (const _typ & _assign) {
_check (_assign);

return _assign;
}

vacío _check (const _typ & _value) {
if (is_within_bounds (_value) == false)
throw std :: exception (“Número fuera del rango máximo”);
}
};

Este es inusual y probablemente el más tedioso. Pero estaba trabajando en la manipulación de bits y pseudobits y, por lo tanto, esto se deriva de allí. Si nada te enseñará algo nuevo 😉

Para darle una breve idea, hay una clase para implementar la funcionalidad ‘bit’ (no puede acceder a bits individuales desde un índice de matriz y jazz similar que no sea el uso de operadores bit a bit). Así que este es un pequeño ayudante ingenioso que me ayuda a hacer números binarios. Por supuesto, esto es solo parte de la implementación completa que escribí, pero es la única parte relevante.

espacio de nombres _bit_representation {
struct _bit_impl {
typedef __int8 small_num;
privado:
small_num _myBit: 1;

static small_num _charASCIItoNum (char _ch) {
return _ch – 48;
}
público:
void _setBit (small_num _val) {
if (_val == 0
|| _val == 1) {
_myBit = _val;
}
}

void _setBit (std :: string _val) {
_setBit (_charASCIItoNum (_val.at (0)));
}

small_num _getBit () {
return _myBit;
}
};

plantilla
clase _binary_num_impl {
público:
typedef __int64 número;
privado:
std :: vector _binary_bits;

std :: string _numToBin (número _val) {
return std :: bitset (_val) .to_string ();
}

número _binToNum (std :: string _val) {
return std :: bitset (_val) .to_ullong ();
}

const std :: string _remove_zero_padding (const std :: string & _val) {
return _val.find (‘1’) == std :: string :: npos? _val: _val.substr (_val.find (‘1’));
}

void _createBinaryNum (std :: string _binaryConverted) {
if (_remove_zero_padding (_binaryConverted) .length ()> _max_number_of_bits && _binaryConverted.find (‘1’)! = std :: string :: npos)
throw std :: exception (“Número fuera del rango máximo”);

size_t _idx = 0;
_binary_bits.resize (_binaryConverted.length ());
std :: for_each (_binary_bits.begin (),
_binary_bits.end (),
[&] (_ bit_impl & _bit) {
if (_binaryConverted.at (_idx)! = ‘\ 0’) {
_bit._setBit (std :: string (& _ binaryConverted.at (_idx)));
++ _ idx;
}
}
);
}
público:
_binary_num_impl () {
_createBinaryNum (“0”);
}

_binary_num_impl (número _num) {
_createBinaryNum (_numToBin (_num));
}

_binary_num_impl (std :: string _binary_num) {
_createBinaryNum (_binary_num);
}

std :: string _getBinaryNumber () {
std :: string _temp;

std :: for_each (_binary_bits.begin (),
_binary_bits.end (),
[&] (_ bit_impl & _bit) {
_temp + = std :: to_string (_bit._getBit ());
});

return _temp;
}

_bit_impl _getBitAt (size_t _idx) {
return _binary_bits [_idx];
}
};
}

// código real para número seguro
plantilla
clase Verified_numeral_using_bit_limits {
_bit_representation :: _ binary_num_impl * _my_binary_number;

público:
Checked_numeral_using_bit_limits () {
_my_binary_number = new _bit_representation :: _ binary_num_impl (0);
}

Checked_numeral_using_bit_limits (_typ _val) {
_my_binary_number = new _bit_representation :: _ binary_num_impl (_val);
}

~ checked_numeral_using_bit_limits () {
eliminar _my_binary_number;
}
};

El tercero, probablemente el más no intuitivo y extraño, usa sizeof. Esto puede usarse raramente, pero puede usarse como una verificación de seguridad de tipo para tipos nativos.

// intento 3
plantilla
clase Verified_numeral_using_size {
_dest_typ safe_numeral;
público:
Checked_numeral_using_size () {
safe_numeral = 0;
}

check_numeral_using_size (_source_typ _val) {
_check (_val);
safe_numeral = static_cast (_val);
}

bool is_size_within_bounds (const _source_typ & _val) {
return (sizeof (_source_typ) <= sizeof (_dest_typ));
}

vacío _check (const _source_typ & _val) {
if (is_size_within_bounds (_val) == false)
throw std :: exception (“Número fuera del rango máximo”);
}

_dest_typ operator = (const _source_typ & _assign) {
_check (_assign);

return static_cast (_assign);
}
};

Y así es como puedes usarlos:

int _tmain (int argc, _TCHAR * argv [])
{
// prueba algunos números fuera de rango
tratar{
chequeado_numeral num1 (40);
}
catch (std :: excepción ex) {
std :: cout << ex.what () << std :: endl;
}

checked_numeral_using_bit_limits num2;
tratar{
num2 = 10;
}
catch (std :: excepción ex) {
std :: cout << ex.what () << std :: endl;
}

tratar{
checked_numeral_using_size num3 (222222222555555.66);
}
catch (std :: excepción ex) {
std :: cout << ex.what () << std :: endl;
}

// prueba algunos números de rango
chequeado_numeral num4 (3); // el rango máximo se voltea automáticamente
checked_numeral_using_bit_limits num5 (1569);
checked_numeral_using_size num6 (1235);

devuelve 0;
}

Por supuesto, necesitará encabezados para ejecutar el código anterior.

usa lo siguiente

#include
#include
#include
#include
#include
#include

Creo que la mayor parte de esto se explica por sí mismo. si no, no dudes en comentar

PD: Sé que los próximos dos intentos son por asesinatos, pero son métodos válidos para diferentes casos. Úsalos con prudencia.

#include
#include
usando el espacio de nombres estándar;

clase safe_integer
{
privado:
valor int = 0.0;
int lower_limit_value = 0.0;
int higher_limit_value = 0.0;

público:
//constructor
safe_integer (int valor_asignado, int menor_limit, int mayor_valor)
{
valor = valor_ asignado;
lower_limit_value = lower_limit;
higher_limit_value = higher_value;
}

int get_lower_limit ()
{
return lower_limit_value;
}

int get_higher_limit ()
{
volver valor_limit_superior;
}

// operador de asignación de sobrecarga =
// Use el conmutador del compilador -fno-short-circuit-optimizar para deshabilitar // la optimización de cortocircuito con gcc
operador vacío = (safe_integer & new_int)
{
if ((new_int.value higher_limit_value))
{
throw std :: runtime_error (“el valor asignado está fuera de rango”);
}
más
{
valor = new_int.value;
}
}

};

int main () {

safe_integer first_integer (0,10,100);
safe_integer second_integer (-200, -100,100);
// Esto arrojará un error

tratar
{
primer_integer = segundo_integer;
// Esto arrojará un error
}
catch (std :: excepción & e)
{
std :: cout << e.what ();
}

devuelve 0;
}

restringiendo el rango de enteros en la definición misma, me temo que C ++ no tiene dicha funcionalidad a menos que desee escribir una función personalizada y agregarla a la biblioteca

la alternativa más simple sería tomar la entrada y luego poner una verificación de condición a través de If

scanf (“% d”, & n); // n es la entrada que tomamos del usuario en c ++ use cin

si (n <10) && (n> 100)

{

printf (“error”);

salida (0);

}

Tienes que escribir tu propia clase para hacerlo.

Los miembros serán

valor int;

int maxlimit;

int minlimit;

Luego debe agregar todas las partes estándar de una clase y tendrá lo que necesita.

Creo que deberías probar esto …

int main () {

cin ›› n;

tratar{

si (n ‹= 10 && n› = 100)

tirar 50;

} catch (int i) {

cout ‹‹ “error”;

}

devuelve 0;

}