Цитата из кода для вычисления целочисленного абсолютного значения (абс) без перехода из 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
и как им пользоваться?
c
bit-manipulation
Дато Датуашвили
источник
источник
CHAR_BIT
?" , даже если это был не исходный вопрос. :( Учитывая ваше объяснение, я понимаю, почему вы написали этот ответ, но для потомков может быть более полезным либо (а) удалить свой ответ и переписать его как комментарий к вопросу, чтобы @AraK был вверху, либо (б) отредактируйте свой ответ так, чтобы он отвечал текущему заголовку вопроса.CHAR_BIT
это количество бит вchar
. В наши дни почти все архитектуры используют 8 бит на байт, но это не всегда так. Некоторые старые машины использовали 7-битный байт.Его можно найти в
<limits.h>
.источник
CHAR_BIT>=8
и допускает гораздо большие значения для DSP, которые имеют только один размер шрифта, часто 32 бита. POSIX требуетCHAR_BIT==8
. В общем, вы можете предположить, что любая многопользовательская / многозадачная серверно-ориентированная или интерактивно-ориентированная архитектура имеет любую возможность подключения к Интернету или обмена текстовыми данными с внешним миромCHAR_BIT==8
.int8_t
иuint8_t
. Таким образом, существует тип ширины 8. Посколькуsizeof
любой тип должен быть совместим, наsizeof char
самом делеsizeof int8_t
должен быть 1. ИтакCHAR_BIT == 8
. Я написал кое-что в связи с этим наблюдением здесь: gustedt.wordpress.com/2010/06/01/how-many-bits-has-a-bytestdint.h
. Таким образом, это требуется, и он также помечен как расширение стандарта ISO C , без ссылки на конкретную версию этого стандарта. Виноват.Попытка ответить как на явный вопрос (что такое CHAR_BIT), так и на неявный (как это работает) в исходном вопросе.
Символ в C и C ++ представляет собой наименьшую единицу памяти, которую программа C может адресовать *
CHAR_BIT в C и C ++ представляет количество бит в char. Всегда должно быть не меньше 8 из-за других требований к типу char. На практике на всех современных компьютерах общего назначения это ровно 8, но некоторые исторические или специализированные системы могут иметь более высокие значения.
Java не имеет эквивалента CHAR_BIT или sizeof, в этом нет необходимости, поскольку все примитивные типы в Java имеют фиксированный размер, а внутренняя структура объектов непрозрачна для программиста. При переводе этого кода на Java вы можете просто заменить sizeof (int) * CHAR_BIT - 1 на фиксированное значение 31.
В этом конкретном коде он используется для вычисления количества бит в int. Имейте в виду, что этот расчет предполагает, что тип int не содержит битов заполнения.
Предполагая, что ваш компилятор выбирает расширение знака при сдвиге битов чисел со знаком, и предполагая, что ваша система использует представление с дополнением 2s для отрицательных чисел, это означает, что «MASK» будет 0 для положительного или нулевого значения и -1 для отрицательного значения.
Чтобы отрицать двоичное дополнение, нам нужно выполнить побитовое отрицание, а затем добавить единицу. Точно так же мы можем вычесть единицу, а затем поразрядно отрицать ее.
Снова предполагая, что представление дополнения до двух, -1 представлено всеми единицами, поэтому исключающее или с -1 эквивалентно поразрядному отрицанию.
Итак, когда v равно нулю, число остается в покое, когда v равно единице, оно отменяется.
Следует знать, что подписанное переполнение в C и C ++ является неопределенным поведением. Таким образом, использование этой реализации ABS для самого отрицательного значения приводит к неопределенному поведению. Это можно исправить, добавив приведение типов, чтобы последняя строка программы оценивалась как целое число без знака.
* Это обычно, но не всегда, то же самое, что и наименьшая единица памяти, которую может адресовать оборудование. Реализация потенциально может объединить несколько единиц памяти с аппаратной адресацией в одну единицу памяти с программной адресацией или разделить одну единицу памяти с аппаратной адресацией на несколько единиц памяти с программной адресацией.
источник