У меня есть 5-битное целое число, с которым я работаю. Есть ли встроенная функция в Objective-C, которая сообщит мне, какой бит является самым левым?Получение самого последнего бита
i.e. У меня есть 01001, он вернет 8 или позицию.
Благодаря
У меня есть 5-битное целое число, с которым я работаю. Есть ли встроенная функция в Objective-C, которая сообщит мне, какой бит является самым левым?Получение самого последнего бита
i.e. У меня есть 01001, он вернет 8 или позицию.
Благодаря
NSInteger value = 9;
NSInteger shift = 1;
for(NSInteger bit = value; bit > 1; bit = value >> ++shift);
NSInteger leftmostbit = 1 << shift;
Работы для каждого количества бит.
Не используйте для этого 'pow'. Там нет языковой гарантии, что 'pow' будет доставлять точную мощность в два раза (это происходит в OS X, что, вероятно, является тем, на что нацеливается, поскольку вопрос помечен как« цель-c », но это не переносное предположение). Это также крайне неэффективно на многих платформах. Вы хотите 'leftmostbit = 1 << shift'. –
Спасибо, ты прав. Я обновил код на основе вашего комментария. – Joost
Вы можете построить таблицу поиска, с 32 элементами: 0, 1, 2, 2, 3 и т.д.
32-элементная таблица поиска - это лучшее решение для этого конкретного случая. –
Даже таблица из 256 элементов хорошо, для 8-битных целых чисел. – ChrisW
@Stephen: только если вы на 100% уверены, что количество бит будет ** всегда ** быть 5 (или, по крайней мере, относительно небольшим числом), и что вы никогда не хотите делать каких-либо оптимизаций, например. SIMD или GPGPU. –
Это фактически ту же операцию, что он рассчитывает число ведущих 0s. Некоторые CPU имеют инструкцию для этого, иначе вы можете использовать трюки, например, найденные в Hacker's Delight.
Он также эквивалентен округлению до ближайшей мощности 2, и снова вы можете найти эффективные методы для этого в Hacker's Delight, например.
uint8_t flp2(uint8_t x)
{
x = x | (x >> 1);
x = x | (x >> 2);
x = x | (x >> 4);
return x - (x >> 1);
}
Смотрите также: Previous power of 2
Stanford Bit Twiddling Hacks есть много примеров того, как это сделать.
Если вы имеете в виду значение любой бит в положении пять из справа («крайний левый» в пять-битное значение), то:
int value = 17;
int bit = (value >> 4) & 1; // bit is 1
Если вы имеете в виду положение левого бита то есть 1:
int value = 2;
int position;
for (position = 0; position < 5; position++) {
int bit = (value >> position) & 1;
if (bit == 1)
break;
}
// position is 1
Позиция будет 0 для бита дальше всего справа, 4 для левого бита ваших пять-битного значения, или 5, если все биты где ноля.
Примечание: это не самое эффективное решение в цикле часов. Надеюсь, это достаточно ясный и образовательный. :)
Я не знаю, Objective C, но это, как я хотел бы сделать это в C.
Pow (2, внутр (log2 (номер))
Это должно дать вам немного самый левый 1 . значение
СМ КОММЕНТАРИЙ Стивеном КОРПОРАЦИИ CANON нИЖЕ ПЕРЕД ИСПОЛЬЗОВАНИЕМ РЕШЕНИЯ
Это невероятно медленно на многих платформах и даст вам неправильный ответ на других (нет гарантии, что функции 'log2' или' pow' правильно округлены - даже для небольших целых чисел - и на многих платформах они не являются). –
@ Stephen Canon - я просто хотел показать еще один метод решения этой проблемы. Возможно, вы правы на медленной проблеме, но вся идея создания каста - избавиться от части дроби, и как только вы это сделаете, pow() всегда вернет вам целые числа. Я не знаю, что log2 и pow имеют проблемы округления. Если это так, то результаты могут пойти не так. – naivnomore
Нет гарантии, что 'pow (2, someInteger)' всегда будет возвращать целое число. Фактически, у меня было несчастье использовать несколько платформ, на которых это не было (несчастливо, но верно). –
Чтобы очистить все биты ниже значащего бита:.
while (x & (x-1)) x &= x - 1;
// 01001 => 01000
Чтобы очистить все биты выше наименьшего значащего бита:
x &= -x;
// 01001 => 00001
Чтобы получить положение только установленный бит в байте:
position = ((0x56374210>>(((((x)&-(x))*0x17)>>3)&0x1C))&0x07);
// 01000 => 3
В libkern.h есть clz
функция, заданная для подсчета ведущих нулей в 32-битном int. Это самая близкая вещь для встроенной функции Objective-C.Для того, чтобы получить позицию самого старшего бита в междунар:
position = 31 - clz(x);
// 01001 => 3
Если вы не хотите использовать табличный, я хотел бы использовать 31 - __builtin_clz(yourNumber)
.
__builtin_clz()
является встроенным компилятором, поддерживаемым gcc, llvm-gcc и clang (и, возможно, другими компиляторами). Он возвращает число начальных нулевых бит в аргументе integer. Вычитая, что от 31
задает позицию бита старшего разряда. Он должен генерировать достаточно быстрый код для любой целевой архитектуры.
С VC++ посмотреть на _BitScanReverse/(64) в
Вы имеете в виду крайний левый бит, который является 1? Это похоже на ваш пример, но ... –