Что такое 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 и как его использовать?
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.hetc. можно определить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