Strtol () и atol () не преобразуют строки длиной более 9 цифр - PullRequest
7 голосов
/ 11 февраля 2011

при работе с приложением, требующим преобразования строк в длинные числа, atol () и strtol () не смогли правильно преобразовать строку длиной более 9 цифр.

strtol запрашивает число, не имеющее отношения к строке, тогда как atol приводит к отрицательному числу (переполнение).

есть идеи, почему это происходит и как я могу это исправить?

Ответы [ 3 ]

8 голосов
/ 11 февраля 2011

Похоже, что long в вашей системе является 32-битным значением. Это означает, что любое число без знака выше 4 294 967 295 не будет преобразовано правильно, а также числа со знаком выше 2 147 483 647 или ниже 2 147 483 648.

Как правило, n -битное представление может представлять числа со знаком в диапазоне [-2 n -1 , - 2 n -1 ) или числа без знака в диапазоне [0,2 n ).

Статья в Википедии Форматы компьютерной нумерации , вероятно, является хорошей отправной точкой, чтобы узнать больше об этом поведении.

Причина, по которой вы видите разные результаты от atol() и strtol(), заключается в том, что они имеют разные характеристики обработки ошибок. Из справочной страницы strtol() :

Функция strtol() возвращает результат преобразования, если только значение не будет уменьшено или переполнено. В случае недостаточного значения strtol() возвращает LONG_MIN. В случае переполнения strtol() возвращает LONG_MAX. В обоих случаях errno устанавливается на ERANGE.

И из atol() справочной страницы :

Функция atoi() преобразует начальную часть строки, на которую указывает nptr, в int. Поведение такое же, как у

strtol(nptr, (char **)NULL, 10);

за исключением того, что atoi() не обнаруживает ошибок.

Функции atol() и atoll() ведут себя так же, как atoi(), за исключением того, что они преобразуют начальную часть строки в свою тип возврата long или long long.

6 голосов
/ 11 февраля 2011

Это, вероятно, связано с размером long на вашей платформе. На 32-битных платформах наибольшее значение, которое умещается в long, равно 2147483647 (2 ^ 31-1), поэтому все, что больше этого, просто не подойдет. Вместо этого используйте long long и strtoll.

0 голосов
/ 11 февраля 2011

Возможно, вы конвертируете в 32-битное целое число. Есть библиотеки, чтобы обойти это.

Попробуйте использовать libgmp , это не накладывает ограничений на размер вашего целого числа.

...