Внутри вашей функции int mx_atoi(const char *str) {...
вы вычисляете результат типа long
, но функция возвращает int
; поэтому, если результат, сохраненный в num
типа long
, не помещается в int
, что-то будет потеряно (на самом деле, поскольку целые значения со знаком преобразованы, поведение "определяется реализацией", то есть зависит от компилятора ). Результат может быть побитово усечен, давая число, которое "выглядит" несколько иначе, чем введенное вами десятичное число. См., Например, это онлайн-черновик C11. Применяется жирный абзац:
6.3.1.3 Целые числа со знаком и без знака
1 Когда значение с целочисленным типом преобразуется в другой целочисленный тип, отличный от _Bool, если значение может быть представлено новым типом, оно не изменяется.
2 В противном случае, если новый тип беззнаковый, значение преобразуется путем многократного добавления или вычитания на единицу больше максимального значения, которое может быть представлено в новом типе до тех пор, пока значение не окажется в диапазоне нового типа. 60)
3 В противном случае новый тип подписывается и значение не может быть представлено в нем; либо результат определяется реализацией, либо возникает сигнал, определяемый реализацией.
Сделать int mx_atoi(const char *str)
до long mx_atoi(const char *str)
, использовать long
-переменную для сохранения результата и не забудьте использовать спецификатор формата %ld
вместо %d
в вашем printf
then.
В противном случае, если вам нужно придерживаться int
и вы хотите безопасно реагировать на переполнения, вы может сделать что-то вроде
if (num > INT_MAX) {
return -1;
}
внутри вашего l oop. INT_MAX
определяется в limits.h