Количество бит в типе данных - PullRequest
4 голосов
/ 19 января 2010

У меня есть две задачи для назначения, одна возвращает количество бит в типе int на любой машине. Я думал, что напишу свою функцию так:

int CountIntBitsF() {
    int x = sizeof(int) / 8;
    return x;
}

Это выглядит правильно?

Вторая часть должна вернуть число любых битов любого типа данных с макросом, и макрос может быть взят из limit.h. Я посмотрел limit.h на своей машине, а также http://www.opengroup.org/onlinepubs/007908799/xsh/limits.h.html,, но я не думаю, что действительно понимаю, как любой из них будет возвращать количество битов в любом типе данных. Какие-нибудь мысли? Спасибо.

Ответы [ 6 ]

15 голосов
/ 19 января 2010

Основной единицей хранения является символ . Это не всегда 8 бит в ширину. CHAR_BIT определен в limit.h и имеет количество бит в символе.

8 голосов
/ 19 января 2010

Это *, а не /.

Что касается второй части, см. Раздел «Числовые пределы».

3 голосов
/ 19 января 2010

Если вы хотите, чтобы количество бит использовалось для хранения целого числа в памяти, используйте ответ Джастина, sizeof(int)*CHAR_BIT. Если вы хотите узнать количество битов, используемых в значении, используйте ответ slebetman.

Хотя, чтобы получить биты в INT, вам, вероятно, следует использовать INT_MAX, а не UINT_MAX. Я не могу вспомнить, действительно ли C99 гарантирует, что int и unsigned int имеют одинаковую ширину или просто они имеют одинаковый размер хранилища. Я подозреваю только последнее, так как в 6.2.6.2 мы имеем «если есть M битов значения в типе со знаком и N в типе без знака, то M <= N», а не «M = N или M = N-1» . </p>

На практике целочисленные типы не имеют битов заполнения в какой-либо реализации, которую я использовал, поэтому вы, скорее всего, получите один и тот же ответ для всех, +/- 1 для знакового бита.

3 голосов
/ 19 января 2010

В limits.h, UINT_MAX - максимальное значение для объекта типа unsigned int. Это означает, что это int со всеми битами, установленными в 1. Итак, считая количество бит в int:

#include <limits.h>

int intBits () {
    int x = INT_MAX;
    int count = 2; /* start from 1 + 1 because we assume
                    * that sign uses a single bit, which
                    * is a fairly reasonable assumption
                    */

    /* Keep shifting bits to the right until none is left.
     * We use divide instead of >> here since I personally
     * know some compilers which does not shift in zero as
     * the topmost bit
     */
    while (x = x/2) count++;

    return count;
}
2 голосов
/ 14 ноября 2012

С g ++ -O2 эта функция оценивается как встроенная константа:

#include <climits>
#include <stddef.h>
#include <stdint.h>
#include <cstdio>

template <typename T>
size_t num_bits()
{
    return sizeof (T) * (CHAR_BIT);
}

int main()
{
    printf("uint8_t : %d\n", num_bits<uint8_t>());
    printf("size_t : %d\n", num_bits<size_t>());
    printf("long long : %d\n", num_bits<long long>());
    printf("void* : %d\n", num_bits<void*>());
    printf("bool : %d\n", num_bits<bool>());
    printf("float : %d\n", num_bits<float>());
    printf("double : %d\n", num_bits<double>());
    printf("long double : %d\n", num_bits<long double>());

    return 0;
}

выходы:

uint8_t : 8
size_t : 32
long long : 64
void* : 32
bool : 8
float : 32
double : 64
long double : 96

Генерируемая 32-битная сборка X86:

--- СНИП ---

movl    $32, 8(%esp)      <--- const $32
movl    $.LC1, 4(%esp)
movl    $1, (%esp)
call    __printf_chk
movl    $64, 8(%esp)      <--- const $64
movl    $.LC2, 4(%esp)
movl    $1, (%esp)
call    __printf_chk

--- СНиП ---

1 голос
/ 19 января 2010

Вы уверены, что хотите количество бит, а не количество байтов? В C для данного типа T вы можете найти количество байтов, которое требуется, используя оператор sizeof. Количество битов в байте равно CHAR_BIT, что обычно равно 8, но может быть другим.

Итак, для типа T число битов в объекте типа T равно:

#include <limits.h>
size_t nbits = sizeof(T) * CHAR_BIT

Обратите внимание, что, за исключением типа unsigned char, все возможные комбинации nbits битов, приведенных выше, могут не представлять действительное значение типа T.

Во второй части обратите внимание, что вы можете применить оператор sizeof к объекту, а также к типу. Другими словами, для данного типа T и объекта x такого типа:

T x;

Размер T можно найти на sizeof(T), а размер x на sizeof x. Скобки не обязательны, если для объекта используется sizeof.

Учитывая приведенную выше информацию, вы сможете ответить на второй вопрос. Спросите еще раз, если у вас все еще есть проблемы.

...