Вычисление максимального размера целого числа со знаком - PullRequest
3 голосов
/ 30 января 2011

Я хотел знать, какое максимальное значение может иметь мое time_t, поэтому я написал небольшую программу, помогающую мне.Требуется один аргумент: количество байтов (1 байт = 8 бит).Я написал это и проверил.Он подходит ко всем значениям от 1 до 4, но при 5 и выше он также редактирует бит со знаком (я не знаю, как он называется).Может кто-нибудь объяснить:

#include <stdio.h>

int main(int argc, const char **argv) {
    if(argc != 2) {
    fprintf(stderr, "Usage: %s bits/8\n", argv[0]);
    return -1;
    }

    unsigned int bytes;
    sscanf(argv[1], "%u", &bytes);

    unsigned int i;
    signed long long someInt = 0;
    size_t max = bytes*8-1;
    for(i = 0; i < max; i++) {
    someInt |= 1 << i;
    }

    /* Print all bits, we substracted 
    1 to use in the previous loop so 
    now we add one again */
    max++;
    for(i = 0; i < max; i++) {
    int isAct = (someInt >> max-i-1) & 1;
    printf("%d", isAct);
    if((i+1) % 8 == 0) {
        printf(" ");
    }
    }
    printf("\n");

    printf("Maximum size of a number with %u bytes of 8 btis: %lld\n", bytes, (long long)someInt);

    return 0;
}

Мое тестирование:

Script started on Sun Jan 30 16:34:38 2011
bash-3.2$ ./a.out 1
01111111 
Maximum size of a number with 1 bytes of 8 btis: 127
bash-3.2$ ./a.out 2
01111111 11111111 
Maximum size of a number with 2 bytes of 8 btis: 32767
bash-3.2$ ./a.out 4
01111111 11111111 11111111 11111111 
Maximum size of a number with 4 bytes of 8 btis: 2147483647
bash-3.2$ ./a.out 5
11111111 11111111 11111111 11111111 11111111 
Maximum size of a number with 5 bytes of 8 btis: -1
bash-3.2$ ./a.out 8
11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111 
Maximum size of a number with 8 bytes of 8 btis: -1
bash-3.2$ exit
exit

Script done on Sun Jan 30 16:35:06 2011

Я надеюсь извлечь уроки из этого, поэтому я был бы очень признателен, если бы кто-то нашел времяпосмотрите на это.

ief2

1 Ответ

1 голос
/ 30 января 2011

Вы используете int, а именно 1, для своей смены.Я думаю, что

someInt |= 1LL << i;

будет лучше, я думаю.

Как правило, я не знаю, как получить максимальное значение целочисленного типа со знаком, для которого у вас есть только typedef безриск неопределенное поведение или специфичные для компилятора и платформы свойства.Например, у оператора << могут быть проблемы со знаковыми типами.

time_t особенно странно, поскольку это может быть тип с плавающей запятой или целочисленный тип.И если это целое число, то не указывается, подписано оно или нет.

Если вы предполагаете, что это целочисленный тип со знаком и , то у вас нет так называемого заполнениябиты (большинство платформ соответствуют этому) максимальное значение может быть вычислено напрямую

((((1LL << (sizeof(time_t)*CHAR_BIT-2)) - 1) << 1) + 1)

без переполнений.

...