Что такое CHAR бит?



цитирование кода для вычисления целого абсолютного значения (abs) без ветвления от http://graphics.stanford.edu / ~seander/bithacks.html:



int v;           // we want to find the absolute value of v
unsigned int r; // the result goes here
int const mask = v >> sizeof(int) * CHAR_BIT - 1;

r = (v + mask) ^ mask;


запатентованный вариант:



r = (v ^ mask) - mask;


что это CHAR_BIT и как его использовать?

661   3  

3 ответов:

вы должны знать, что этот код зависит от реализации определенного поведения right bitshift на подписанных типах. gcc обещает всегда давать нормальное поведение (знак-бит-расширение), но ISO C позволяет реализовать нулевое заполнение верхних битов.

один из способов обойти эту проблему:

#ifdef HAVE_SIGN_EXTENDING_BITSHIFT
int const mask = v >> sizeof(int) * CHAR_BIT - 1;
#else
int const mask = -((unsigned)v >> sizeof(int) * CHAR_BIT - 1);
#endif

код Makefile или config.h etc. можно определить HAVE_SIGN_EXTENDING_BITSHIFT во время сборки в зависимости от вашей платформы.

CHAR_BIT - Это количество битов в char. В наши дни почти все архитектуры используют 8 бит на байт, но это не всегда так. Некоторые старые машины раньше имели 7-битный байт.-

его можно найти в <limits.h>

попытка ответить как на явный вопрос (Что такое CHAR_BIT), так и на неявный вопрос (как это работает) в исходном вопросе.


символ в C и C++ представляет собой наименьшую единицу памяти, которую программа C может адресовать*

CHAR_BIT в C и C++ представляет количество битов в символе. Он всегда должен быть не менее 8 из-за других требований к типу char. На практике на всех современных компьютерах общего назначения именно 8, но некоторые исторические или специализированные системы могут иметь более высокие значения.

Java не имеет эквивалента CHAR_BIT или sizeof, в этом нет необходимости, так как все примитивные типы в Java имеют фиксированный размер, а внутренняя структура объектов непрозрачна для программиста. При переводе этого кода на Java вы можете просто заменить "sizeof (int) * CHAR_BIT - 1" на фиксированное значение 31.

в этом конкретном коде он используется для вычисления количества битов в int. Имейте в виду, что этот расчет предполагает, что тип int не содержит какие-либо биты заполнения.

предполагая, что ваш компилятор решает подписать extend на битовых сдвигах подписанных чисел и предполагая, что ваша система использует представление дополнения 2s для отрицательных чисел, это означает, что "маска" будет равна 0 для положительного или нулевого значения и -1 для отрицательного значения.

чтобы отрицать число дополнения двоек, нам нужно выполнить побитовое не, а затем добавить один. Равным образом мы можем вычесть один, а затем побитово отрицать оно.

снова предполагая, что представление дополнения двоек -1 представлено всеми единицами, поэтому исключающее ИЛИ с -1 равнозначно побитовому отрицанию.

поэтому, когда v равно нулю, число остается в покое, когда v равно единице, оно отрицается.

следует помнить, что переполнение со знаком в C и C++ является неопределенным поведением. Таким образом, использование этой реализации ABS на самом отрицательном значении приводит к неопределенному поведению. Это может быть исправлено путем добавления приведений таким образом, что последняя строка программа оценивается в unsigned int.

* что обычно, но не всегда совпадает с наименьшей единицей памяти, которую может адресовать аппаратное обеспечение. Реализация потенциально может объединить несколько единиц аппаратно-адресуемой памяти в одну единицу программно-адресуемой памяти или разделить одну единицу аппаратно-адресуемой памяти на несколько единиц программно-адресуемой памяти.

Comments

    Ничего не найдено.