Нахождение n-битной длины 2-х дополнительных представлений числа

Пишу функцию с параметрами:

int nbit2s(long int x, long int n){

}

Я хочу взять 64-битное число x и выяснить, возможно ли 2-битное представление длины n в битах. Однако я ограничен использованием только побитовых операторов и исключен из использования таких операторов, как >= ‹= и условных операторов.

Например, nbit2s(5,3) возвращает 0, потому что представление невозможно.

Я не ищу никакого кода, а просто идеи, до сих пор моя идея была:

  1. Возьмите число n и преобразуйте его в двоичное представление.
  2. Сдвиг влево двоичного представления 64-n раз, чтобы получить MSB и сохранить его в переменной shift 3.Сдвиг вправо 64-n, чтобы получить начальный бит и сохранить в сдвиге
  3. Исходное число XOR с W, если 1, то TRUE, 0, то FALSE.

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


person Bob Dylan    schedule 29.01.2016    source источник
comment
long int x может быть только 32-битным. Рекомендую long long или uint64_t.   -  person chux - Reinstate Monica    schedule 29.01.2016
comment
У меня сложилось впечатление, что long int был 64-битным на машине Mac и оставался 32-битным на машинах с Windows.   -  person Bob Dylan    schedule 29.01.2016
comment
Я чувствую, что вы делаете тот же курс: stackoverflow.com/questions/9122636/ stackoverflow.com/questions/8204075/   -  person viraptor    schedule 29.01.2016
comment
Я считаю, что это ответ, который вы ищете stackoverflow.com/a/16105238/1772838   -  person Parker Hoyes    schedule 29.01.2016


Ответы (2)


Если я правильно понимаю ваш вопрос, вы хотели бы определить, может ли целое число x быть представлено как двоичное число с n или менее битами.

Простой способ проверить это — использовать побитовый оператор И, чтобы замаскировать все биты выше максимального значения, а затем посмотреть, совпадает ли замаскированное целое с исходным.

Пример:

bool nbit2s(uint64_t x, int n) {
    return (x & (1ULL << n) - 1) == x;
}
person Parker Hoyes    schedule 29.01.2016
comment
1 << n не может сдвигать 64 бита, так как int 1 может быть узким. Лучше использовать 1ULL << n или подобное - person chux - Reinstate Monica; 29.01.2016
comment
Это работает только для беззнаковых чисел. В вопросе есть отрицательные. - person viraptor; 29.01.2016

Решением для положительных чисел будет просто сдвиг вправо на n. Если он все еще не равен нулю, то для его представления требуется больше n бит.

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

person viraptor    schedule 29.01.2016