В чем разница между strtol и strtoul?

Я встретил какой-то незаметный результат strtol в c

вот пример программы.

#include <string.h>
#include <stdio.h>    
#include <stdlib.h>

int main()
{
    printf("%xn", strtol("0xfffff70A", NULL, 0));
    return 0;
}

и выход этой простой программы

0x7fffffff

, а не 0xfffff70A. И если я использую strtoul, результат точно 0xfffff70a. Я использую 32-битную машину, и мне интересно, что происходит. ПС. Я использую gcc 4.7.2

3 ответов


из пункта 8.22.1.4 (of проект стандарта n1570 издания 2011 года):

если правильное значение находится вне диапазона представимых значений, LONG_MIN, LONG_MAX, LLONG_MIN, LLONG_MAX, ULONG_MAX или ULLONG_MAX возвращается (в соответствии с типом возврата и знаком значения, если таковые имеются) и значением макроса ERANGE сохраняется в errno.

так как правильное значение вашей входной строки слишком велико для тип, вы получите LONG_MAX и errno установлено значение ERANGE.

когда strto(u)l(l) функции возвращает один из TYPE_MAX или TYPE_MIN значения, вам нужно проверить errno чтобы узнать, является ли это правильным результатом, или ваш вход был вне диапазона.


вы сталкиваетесь с переполнением long тип, который подписывается.

вы, вероятно, следует использовать:

print("%lx\n", strtoul("0xfffff70a", NULL, 0));
                    ^
                    |
                 important!

вместо этого отметьте " u " для " unsigned "(см. страница руководства).

Также обратите внимание, что вы не можете напечатать unsigned long простой %x, вы должны квалифицировать его как больше, чем int.


ваша архитектура имеет 32-битный long тип. 0xfffff70A не представляется в виде подписанного 32-разрядного long. errno должно быть установлено в ERANGE.

в дополнении 2 представимые значения для 32-разрядных целых чисел со знаком варьируются от -0x80000000 to 0x7fffffff.