2011-01-30 4 views
3

Я хотел знать, какое максимальное значение может иметь мой 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

Вы только с помощью int, а именно 1, для операции сдвига. Это

someInt |= 1LL << i; 

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

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

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

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

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

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

+0

Большое спасибо, добавив 'LL' к моей целочисленной константе, которая действительно решает мою проблему. 'Time_t' определяется как' /usr/include/i386/_types.h:typedef long __darwin_time_t; 'на моей платформе Mac OS X. Я не знаю, что такое биты для заполнения, но в любом случае мой исполняемый файл работает сейчас. – v1Axvw

+1

Вместо того, чтобы '1LL',' (time_t) 1' было бы лучше. Он работает, даже если 'time_t' больше, чем' long long' (расширенный целочисленный тип). –