Преобразование огромных чисел

378
27 января 2017, 06:35

Преобразую значения из string в long long

val = atoll(a[i].c_str());

Как защититься от Васи Пупкина, который записал число, которое большее максимального (9223372036854775807)? Нужно приравнивать val к 0.

Программа ошибок не выдаёт, однако наличие такой недоработки меня напрягает.

Answer 1

Ну, как вариант - использовать stoll и перехватывать исключения...

int main(int argc, const char * argv[])
{
    string s;
    cin >> s;
    long long l;
    try {
        l = stoll(s);
    } catch(out_of_range&)
    {
        l = 0;
    } catch(invalid_argument&)
    {
        l = -1;
    }
    cout << "s = " << s << endl;
    cout << "l = " << l << endl;
}
Answer 2

Функции группы ato.. были [полу-]официально "покинуты" стандартом языка С еще в 1995 году (cм. http://www.open-std.org/jtc1/sc22/wg14/www/C99RationaleV5.10.pdf). Они не предоставляют никаких средств для обработки ошибочных ситуаций. В стандартной библиотеке С им на смену пришли функции группы strto..., которые предоставляют такие средства.

Эти функции не были официально объявлены obsolescent из-за их широкой распространенности в старом коде. Также они потенциально могу быть реализованы более эффективно, чем функции группы strto.... Однако реальные реализации этим обычно не занимаются, а просто делегируют вызовы ato... в strto... с игнорированием потенциальных ошибок.

Поэтому если вы по какой-то причине настаиваете на использовании С-функций для решения подобных задач, забудьте о существовании функций группы ato... - это "мертвые" функции. Пользуйтесь функциями группы strto....

Разумеется, учитывая, что ваш вопрос помечен тегом [C++], вам лучше просто воспользоваться аналогичными средствами стандартной библиотеки С++.

Answer 3

Это наиболее быстрая реализация приведения, из мне известных. Она да, требует некоторую проверку на этапе компиляции, но работает, как часы. В цикл while (*p >= '0' && *p <= '9') надо добавить проверку на длину строки, соответствующую длине максимального числа. Типом возвращаемого значения можно играть. Должно работать в разы быстрее зачтенного варианта.

  STATIC_ASSERT(1 == '1' - '0');
  STATIC_ASSERT(2 == '2' - '0');
  STATIC_ASSERT(3 == '3' - '0');
  STATIC_ASSERT(4 == '4' - '0');
  STATIC_ASSERT(5 == '5' - '0');
  STATIC_ASSERT(6 == '6' - '0');
  STATIC_ASSERT(7 == '7' - '0');
  STATIC_ASSERT(8 == '8' - '0');
  STATIC_ASSERT(9 == '9' - '0');
  int to_int(const char *p)
  {
     while (*p == ' ')
        ++p;
     int r = 0;
     bool neg = false;
     if (*p == '-') {
        neg = true;
        ++p;
     }
     while (*p >= '0' && *p <= '9') {
        r = (r*10) + (*p - '0');
        ++p;
     }
     if (neg) {
        r = -r;
     }
     return r;
  }
Answer 4
std::string s="922337203685477580712324567878";
size_t index;
long long l=std::stoll(s, &index);
if(index!=s.size())
    throw std::runtime_error("bad number");
READ ALSO
Ошибка при обновлении данных в MySQL

Ошибка при обновлении данных в MySQL

Есть таблица в базе данных

310
Запросы на api Post на Авторизацию

Запросы на api Post на Авторизацию

Можете подсказать , мне надо понять и научиться как написать POST запрос на сервером (https://inecopayru/inecogate/doc/dist/index

394
Конвертация строки в коды символов Unicode

Конвертация строки в коды символов Unicode

Имею приложение2 EditText, один - поле ввода текста в utf, второй - вывод преобразованного текста в формате \uXXXX\uXXXX\uXXXX Я ввожу: "Привет", а в ответ должен...

343