Как я могу получить доступ к знаку бит числа в C ++? - PullRequest
8 голосов
/ 09 июня 2010

Я хочу иметь возможность получить доступ к знаку бита числа в C ++. Мой текущий код выглядит примерно так:

int sign bit = number >> 31;

Это похоже на работу, давая мне 0 для положительных чисел и -1 для отрицательных чисел. Тем не менее, я не вижу, как я получаю -1 для отрицательных чисел: если 12 равно

0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 1100

тогда -12 это

1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 0011

и сдвиг его на 31 бит составит

0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0001

это 1, а не -1, так почему я получаю -1, когда меняю его?

Ответы [ 8 ]

27 голосов
/ 09 июня 2010

Как насчет этого?

int sign = number < 0;

14 голосов
/ 09 июня 2010

Результат смещения вправо отрицательного числа в C ++ определяется реализацией.Так что никто не знает, что должно произойти смещением вправо -12 на вашей конкретной платформе.Вы думаете, что это должно сделать выше (1), в то время как я говорю, что это может легко произвести паттерн «все единицы», который равен -1.Последнее называется сдвигом со знаком.При расширенном смещении знака бит знака копируется вправо, но не сдвигается со своего места.

Если все, что вас интересует, это значение знака бит, то прекратите тратить время, пытаясь использовать битовуюоперации, например сдвиги и т. д. Просто сравните свое число с 0 и посмотрите, отрицательно оно или нет.

8 голосов
/ 09 июня 2010

Потому что вы меняете целое число со знаком. Приведите целое число к неподписанному:

int sign_bit = ((unsigned int)number) >> 31;
7 голосов
/ 10 марта 2015

Вы можете использовать библиотеку cmath

#include <cmath>

и использовать ее как

std::cout << std::signbit(num);

Эта функция получает значение с плавающей запятой в качестве ввода и значение bool в качестве вывода.

true for negative
false for positive

например

std :: cout << std :: signbit (1); </p>

даст вам 0 в качестве вывода (false)

но при использовании этой функции вы должны быть осторожны с нулем

std::cout << std::signbit(-0.0);  // 512 (true)
std::cout << std::signbit(+0.0);  // 0   (false)

Вывод этих строк не совпадает.

Чтобы устранить эту проблему, вы можете использовать:

float x = +0.01;
std::cout << (x >= 0 ? (x == 0 ? 0 : 1) : -1);

, которые дают:

 0 for 0
 1 for positive
-1 for negative
4 голосов
/ 17 ноября 2011

Для целых чисел, проверьте number < 0.

Для чисел с плавающей запятой, вы также можете принять во внимание тот факт, что ноль имеет знак.То есть существует -0.0, отличное от +0.0.Чтобы различать два, вы хотите использовать std :: signbit .

2 голосов
/ 09 июня 2010

Оператор >> выполняет арифметическое смещение , в котором сохраняется знак числа.

1 голос
/ 06 декабря 2013
bool signbit(double x)
{
    return 1.0/x != 1.0/fabs(x);
}

Мое решение, поддерживающее +/- 0.

0 голосов
/ 24 июня 2015
bool signbit(double x)
{
    return (__int64)x & 0x8000000000000000LL != 0LL;
}

bool signbit(float x)
{
    return (__int32)x & 0x80000000 != 0;
}
...