Как сделать проверку на то, помещается ли значение в int?

141
12 апреля 2019, 04:00

Вот программа, которая по сути выводит сумму первых N элементов вектора. Как выводить ошибку при попытке записи в int слишком большого числа? В данном случае в tmpint и в sum.

#include "std_lib_facilities.h"
using namespace std;
int main()
try {
    vector<int> vals;                                       // Ряд целых чисел  
    int tmpval,                                             // Ввод целых числе
        sum = 0;                                            // Сумма первых sum_count элементов вектора vals
    int sum_count;                                          // Количество суммируемых значений, число натуральное
    cout << "Введите количество суммируеммых значений: ";
    cin >> sum_count;                                       // Ввод количества слогаемых с клавиатуры
    if (sum_count <= 0 || !cin)                             // Условие: число натуральное
        error("Введено неверное значение кол-ва слогаемых");
    cout << "Введите через пробел ряд (не менее " << sum_count 
        << ") целочисленных значений,\nдля остановки используйте любой символ, но не цифру: ";   
    while (cin >> tmpval)                                   // Заполнение вектора значениями    
        vals.push_back(tmpval);         
    if ((unsigned int)(sum_count) > vals.size())            // Условие: количество слогаемых не меньше количества элементов вектора vals
        error("Количество слогаемых не может быть меньше количества введённых чисел");
    for (int i = 0; i < sum_count; i++)                     // Счет суммы первых sum_count слогаемых
        sum += vals[i];
    cout << "Сумма первых " << sum_count << " значений (";  // Вывод количества значений, 
    for (int i = 0; i < sum_count; i++) {                   // самих значений и их суммы
        cout << vals[i];
        if (i != sum_count - 1) {
            cout << ' ';
        }
    }
    cout << ") равна: " << sum;
    return 0;
} 
catch (runtime_error &e) {
    cerr << "[ERROR] " << e.what() << '\n';
    return 1;
}
Answer 1

В принципе проверка на переполнение очень проста. Если у нас два положительных числа, то сумма этих чисел не может быть меньше любого из двух слагаемых. И наоборот сумма двух отрицательных чисел не может быть больше любого из двух слагаемых.

Пример кода:

short sum = 0x7FFF;
short val = 1;
if (sum > 0 && val > 0 && sum > (short)(sum + val))
    std::cout << "overflow +";
sum = 0x8000;
val = -1;
if (sum < 0 && val < 0 && sum < (short)(sum + val))
    std::cout << "overflow -";

Вообще переполнение не является чем то из ряда вон. Это нормальное поведение бинарных чисел. И, с точки зрения разработки, нужно просто предусмотреть достаточную разрядность переменной для корректного результата. В Вашем случае это например может быть тип long long.

Answer 2

Можно воспользоваться библиотекой SafeInt:

#include <safeint.h>
try
{
    ::std::vector<int> vals{};
    ::msl::utilities::SafeInt<decltype(vals)::value_type> sum{};
    ::std::size_t sum_count{};
    ...
    {
        ::std::size_t value_index{};
        while(sum_count != value_index)
        {
             sum += vals[value_index];
             ++value_index;
        }
    }
}
catch(::msl::utilities::SafeIntException const & exception)
{
}
catch (::std::runtime_error const & e)
{
}
Answer 3

Просто процитирую ответ с английского SO:

if (a^b < 0) overflow=0; /* opposite signs can't overflow */
else if (a>0) overflow=(b>INT_MAX-a);
else overflow=(b<INT_MIN-a);

Оригинал: https://stackoverflow.com/questions/6970802/test-whether-sum-of-two-integers-might-overflow

READ ALSO
Функция setprecision c/c++ Особенности компиляторов

Функция setprecision c/c++ Особенности компиляторов

Написал вот такой код на visual-studio-2017:

165
Как в масив строк добавить ещё одну

Как в масив строк добавить ещё одну

Всё не так просто как кажется =) Есть переменная It, так вот её нужно вставить вместо The body of the message starts here\r\n Вот код =)

148
Помогите решить задачу 763 [закрыт]

Помогите решить задачу 763 [закрыт]

На бесконечной вправо и вверх шахматной доске находится ладьяДва игрока передвигают ее по очереди

157
Не знаю, как вывести максимальное число подпоследовательностей

Не знаю, как вывести максимальное число подпоследовательностей

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

130