Форум программистов, компьютерный форум CyberForum.ru

С++ для начинающих

Войти
Регистрация
Восстановить пароль
 
 
Рейтинг: Рейтинг темы: голосов - 10, средняя оценка - 4.60
DarkMasterW
4 / 4 / 0
Регистрация: 25.10.2013
Сообщений: 227
#1

Что если число будет слишком большим и не поместиться в int? - C++

17.03.2014, 05:23. Просмотров 1316. Ответов 37
Метки нет (Все метки)

Собственно есть char*, надо в int. Вроде есть atoi для этих целей. Но тут появляется пара неудобных вопросов:
1) Что если число будет слишком большим и не поместиться в инт?
2) Скорее теоретически, т.к. не цифры отсекаются при формировании входного char*, но тем не менее: что если в char* будут не только цифры?

Спасибо.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
17.03.2014, 05:23     Что если число будет слишком большим и не поместиться в int?
Посмотрите здесь:

Что означает конструкция int(cls::*), если cls - это класс ? C++
Что будет если так сделать? C++
C++ Дано натуральное число N. Напишите функцию int NumberOfZeroes(int n) (C/C++/Java)
C++ Как в выделенную память записать поочередно число int, массив char[n], и еще число int
Для чего используется _getch() и что будет, если ее не использовать? C++
C++ Как получить число типа int, если имеется указатель на строку с этим числом?
C++ Зачем преобразовывать itsVal в int, если эта переменная и так объявлена как тип int
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
Tulosba
:)
Эксперт С++
4387 / 3230 / 297
Регистрация: 19.02.2013
Сообщений: 9,044
17.03.2014, 14:05     Что если число будет слишком большим и не поместиться в int? #21
Цитата Сообщение от alsav22 Посмотреть сообщение
через функции типа atoi, получится число больше предельно допустимого, то оно будет автоматически обрезано до максимально допустимого
Судя по описанию atoi, при выходе за пределы будет UB:
If the converted value would be out of the range of representable values by an int, it causes undefined behavior.
Поэтому, всё же лучше использовать strtol.
alsav22
5413 / 4809 / 442
Регистрация: 04.06.2011
Сообщений: 13,587
17.03.2014, 14:53     Что если число будет слишком большим и не поместиться в int? #22
Цитата Сообщение от Tulosba Посмотреть сообщение
Поэтому, всё же лучше использовать strtol.
Если строковый поток?
Tulosba
:)
Эксперт С++
4387 / 3230 / 297
Регистрация: 19.02.2013
Сообщений: 9,044
17.03.2014, 15:10     Что если число будет слишком большим и не поместиться в int? #23
Цитата Сообщение от alsav22 Посмотреть сообщение
Если строковый поток?
Не понял вопроса.
alsav22
5413 / 4809 / 442
Регистрация: 04.06.2011
Сообщений: 13,587
17.03.2014, 15:20     Что если число будет слишком большим и не поместиться в int? #24
Цитата Сообщение от Tulosba Посмотреть сообщение
Не понял вопроса.
Строковый поток корректно обрабатывает такие ситуации? Если получается число больше предельно допустимого для типа переменной?
Tulosba
:)
Эксперт С++
4387 / 3230 / 297
Регистрация: 19.02.2013
Сообщений: 9,044
17.03.2014, 16:46     Что если число будет слишком большим и не поместиться в int? #25
Цитата Сообщение от alsav22 Посмотреть сообщение
Строковый поток корректно обрабатывает такие ситуации?
Тут не строковый поток надо смотреть, а operator>>(int&) и т.п. для std::istream. На тесте:
C++
1
2
3
4
5
6
7
8
9
10
11
12
#include <iostream>
     
int main() {
     
    int i;
    std::cin >> i;
     
    std::cout << i << std::endl;
    std::cout << std::boolalpha << std::cin.fail() << std::endl;
     
    return 0;
}
http://ideone.com/GkDNy2
видно, что при переполнении fail() возвращает true.
alsav22
5413 / 4809 / 442
Регистрация: 04.06.2011
Сообщений: 13,587
17.03.2014, 17:55     Что если число будет слишком большим и не поместиться в int? #26
Цитата Сообщение от Tulosba Посмотреть сообщение
видно, что при переполнении fail() возвращает true.
При этом, значение переменной станет равно...?
Tulosba
:)
Эксперт С++
4387 / 3230 / 297
Регистрация: 19.02.2013
Сообщений: 9,044
17.03.2014, 18:13     Что если число будет слишком большим и не поместиться в int? #27
Цитата Сообщение от alsav22 Посмотреть сообщение
При этом, значение переменной станет равно...?
По ссылке видно
alsav22
5413 / 4809 / 442
Регистрация: 04.06.2011
Сообщений: 13,587
17.03.2014, 18:30     Что если число будет слишком большим и не поместиться в int? #28
Цитата Сообщение от Tulosba Посмотреть сообщение
По ссылке видно
У меня такое выводит: -858993460. Стандарт что-нибудь по этому поводу говорит?
Tulosba
:)
Эксперт С++
4387 / 3230 / 297
Регистрация: 19.02.2013
Сообщений: 9,044
18.03.2014, 12:30     Что если число будет слишком большим и не поместиться в int? #29
Цитата Сообщение от alsav22 Посмотреть сообщение
Стандарт что-нибудь по этому поводу говорит?
22.4.2.1.2/3 Stage 3:
The numeric value to be stored can be one of:
— zero, if the conversion function fails to convert the entire field. ios_base::failbit is assigned to err.
— the most positive representable value, if the field represents a value too large positive to be represented in val. ios_base::failbit is assigned to err.
— the most negative representable value or zero for an unsigned integer type, if the field represents a value too large negative to be represented in val. ios_base::failbit is assigned to err.
— the converted value, otherwise.
Цитата Сообщение от alsav22 Посмотреть сообщение
У меня такое выводит: -858993460.
Это скорее всего просто не инициализированное значение переменной. У меня 2010 студия например так же себя ведет. Т.е. получается, что не по стандарту. Хотя цитата ведь из C++11, а в C++03 могло быть другое поведение, хотя бы потому, что тогда не было strtoll().
alsav22
5413 / 4809 / 442
Регистрация: 04.06.2011
Сообщений: 13,587
18.03.2014, 12:47     Что если число будет слишком большим и не поместиться в int? #30
Цитата Сообщение от Tulosba Посмотреть сообщение
Т.е. получается, что не по стандарту.
Получается, что и atoi(), в студии, себя не по стандарту ведёт: вместо UB, просто выдаёт максимально допустимое значение для типа (поэтому, в начале темы, и написал).
Tulosba
:)
Эксперт С++
4387 / 3230 / 297
Регистрация: 19.02.2013
Сообщений: 9,044
18.03.2014, 13:04     Что если число будет слишком большим и не поместиться в int? #31
Цитата Сообщение от alsav22 Посмотреть сообщение
вместо UB, просто выдаёт максимально допустимое значение для типа
Так UB на то и UB, что может быть и такой вариант

Добавлено через 7 минут
Посмотрел в С++03 22.2.2.1.2/11:
Stage 3:
The result of stage 2 processing can be one of
— A sequence of chars has been accumulated in stage 2 that is converted (according to the rules of scanf) to a value of the type of val. This value is stored in val and ios_base::goodbit is stored inerr.
— The sequence of chars accumulated in stage 2 would have caused scanf to report an input failure. ios_base::failbit is assigned to err.
Т.е. в случае ошибки про итоговое значение ничего не сказано. Следовательно, м.б. любым. И, кстати, про использование atoi() в этой цепочке ничего не сказано.
alsav22
5413 / 4809 / 442
Регистрация: 04.06.2011
Сообщений: 13,587
18.03.2014, 13:04     Что если число будет слишком большим и не поместиться в int? #32
Цитата Сообщение от Tulosba Посмотреть сообщение
Так UB на то и UB, что может быть и такой вариант
В студии может быть какой-либо другой вариант? Если да, то как получить другой вариант? Если нет, то в чём тогда UB?
Tulosba
:)
Эксперт С++
4387 / 3230 / 297
Регистрация: 19.02.2013
Сообщений: 9,044
18.03.2014, 13:20     Что если число будет слишком большим и не поместиться в int? #33
Цитата Сообщение от alsav22 Посмотреть сообщение
В студии может быть какой-либо другой вариант?
2010 и 2012 студии ведут себя одинаково. При выходе из диапазона значение переменной не меняют (т.е. внутри они конечно возвращают LONG_MIN или LONG_MAX, но до пользователя оно не доходит), устанавливают errno = ERANGE;
Можете сами попробовать пройтись отладчиком.
Цитата Сообщение от alsav22 Посмотреть сообщение
Если нет, то в чём тогда UB?
Разговор про UB был относительно atoi(), если я ничего не путаю. А при чтении числа из потока (std::istream) atoi() не используется по факту. Есть фактически нечто похожее на требование C++11 (всякие _Stoulx() вместо std::strtoull()), но итоговое поведение не соответствует C++11.
alsav22
5413 / 4809 / 442
Регистрация: 04.06.2011
Сообщений: 13,587
18.03.2014, 13:33     Что если число будет слишком большим и не поместиться в int? #34
Цитата Сообщение от Tulosba Посмотреть сообщение
Разговор про UB был относительно atoi(), если я ничего не путаю.
Я про неё и спрашиваю. В студии atoi(), при числе больше максимально допустимого, возвращает максимально допустимое.
Цитата Сообщение от Tulosba Посмотреть сообщение
Так UB на то и UB, что может быть и такой вариант
Цитата Сообщение от alsav22 Посмотреть сообщение
В студии может быть какой-либо другой вариант? Если да, то как получить другой вариант? Если нет, то в чём тогда UB?
Tulosba
:)
Эксперт С++
4387 / 3230 / 297
Регистрация: 19.02.2013
Сообщений: 9,044
18.03.2014, 13:49     Что если число будет слишком большим и не поместиться в int? #35
Цитата Сообщение от alsav22 Посмотреть сообщение
Я про неё и спрашиваю.
atoi() это сишная функции и описание следует смотреть в сишном стандарте уже. Вот в C99 такое есть:
7.20.1 Numeric conversion functions:
The functions atof, atoi, atol, and atoll need not affect the value of the integer expression errno on an error. If the value of the result cannot be represented, the behavior is undefined.
Если студия ведет себя более очевидным образом это ей только в плюс. Но не стоит надеяться, что другие реализации будут вести себя аналогично.
alsav22
5413 / 4809 / 442
Регистрация: 04.06.2011
Сообщений: 13,587
18.03.2014, 14:28     Что если число будет слишком большим и не поместиться в int? #36
Цитата Сообщение от Tulosba Посмотреть сообщение
Если студия ведет себя более очевидным образом это ей только в плюс. Но не стоит надеяться, что другие реализации будут вести себя аналогично.
Я правильно понял, что в студии это не UB?
Tulosba
:)
Эксперт С++
4387 / 3230 / 297
Регистрация: 19.02.2013
Сообщений: 9,044
18.03.2014, 14:40     Что если число будет слишком большим и не поместиться в int? #37
Цитата Сообщение от alsav22 Посмотреть сообщение
Я правильно понял, что в студии это не UB?
Как себя ведёт студия, надо смотреть в доке по студии.
http://msdn.microsoft.com/en-us/library/yd5xkb5c.aspx
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
18.03.2014, 14:51     Что если число будет слишком большим и не поместиться в int?
Еще ссылки по теме:

C++ Что будет, если два раза динамически выделить память по одному указателю?
Бросают 5 игральных костей, какова вероятность, что выпавшее число будет четным? C++
C++ Работа со стеком. Если массив нужен float, а не int, что необходимо изменить
Intel Intrinsic. Что будет, если объявить много __m128 переменных? C++
C++ Найти сумму положительных элементов массива и узнать будет ли число простым, если округлить его до целого

Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
alsav22
5413 / 4809 / 442
Регистрация: 04.06.2011
Сообщений: 13,587
18.03.2014, 14:51     Что если число будет слишком большим и не поместиться в int? #38
Значит, в студии, это не UB.
Yandex
Объявления
18.03.2014, 14:51     Что если число будет слишком большим и не поместиться в int?
Ответ Создать тему
Опции темы

Текущее время: 14:34. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru