Как очистить биты с помощью побитовых операторов

Мне интересно узнать, как очистить биты, чтобы я мог использовать часть двоичного значения вместо целого. Я надеюсь использовать это для получения подписанного бита, показателя степени и значения из формы с плавающей запятой IEEE с одинарной точностью.

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

Вот мои мысли до сих пор:
Бит со знаком — побитовое И-двоичное значение на 0x100000000, чтобы получить только первый бит

Экспонент — сдвиньте значение влево один раз, а затем — и новое значение на 0xFF000000, чтобы получить
первые восемь битов для показателя степени

Significand — сдвинуть значение влево в 23 раза

Поскольку каждый из них потребует выполнения работы с исходным значением, я планирую также сохранить значение в другом регистре. Таким образом, я все еще могу работать с ценностью, не «вредя» оригиналу. Значение бит со знаком, экспоненты и signficand будут сохранены в отдельных регистрах.

2

Решение

ПРИМЕЧАНИЕ. Я имею в виду формат с плавающей запятой IEEE-754 с одинарной точностью для этого ответа:

Знак: И-маску свой номер с 0x80000000, Если результат равен 0, число положительное, иначе отрицательное.
Экспонент: И-маску свой номер с 0x7F800000, затем сдвиньте 23 бита вправо.
Мантисса: И-маскируй свой номер 0x007FFFFF,

Чтобы понять, почему я использовал эти числа, просто преобразуйте каждую маску в двоичную форму и поместите ее под двоичное представление вашего числа с плавающей запятой:

SEEEEEEEEMMMMMMMMMMMMMMMMMMMMMMM = format of a floating point number: S=sign,
E=exponent,
M=mantisa
10000000000000000000000000000000 = 80000000h  (isolate sign bit)
01111111100000000000000000000000 = 7F800000h  (isolate exponent, 8 bits)
00000000011111111111111111111111 = 007FFFFFh  (isolate mantissa, 23 bits)

Чтобы преобразовать двоичное число в шестнадцатеричное, просто сгруппируйте его в 4-битные группы и преобразуйте каждую группу в шестнадцатеричное число:

Например:

01111111100000000000000000000000 is arranged as:
0111 1111 1000 0000 0000 0000 0000 0000  which is translated into hex as this:
7     F    8    0    0    0    0    0
1

Другие решения

Вот немного синтаксиса NASM 32 бит

MOV eax, DWORD [ssValue]
MOV ebx, DWORD [signMask] ;; 80000000h
MOV ecx, DWORD [expoMask] ;; 7F800000h
MOV edx, DWORD [sigfMask] ;; 007FFFFFh
AND ebx, eax
AND ecx, eax
AND edx, eax ;; edx is the significand
SHR ebx, 31 ;; ebx is the sign
SHR ecx, 23 ;; ecx is the exponent

В C это было бы что-то вроде

int sign = value & 0x80000000;
int expo = value & 0x7F800000;
int sigf = value & 0x007FFFFF;
sign >>= 31;
expo >>= 23;

РЕДАКТИРОВАТЬ, если вы хотите исправить показатель, который имеет смещение 127 (7Fh)

if(expo == 0x0) {
// denormal
} else if(expo == 0xFF) {
// +inf or nan depending on sigf
} else { // -126 to 127 range
expo -= 0x7F;
}

РЕДАКТИРОВАТЬ 2
В других языках, таких как Java, «>>» является оператором сдвига со знаком.

sign >>= 31; // would result in 0 or -1 (0xFFFFFFFF) if the sign bit was 1
sign >>>= 31; // would result in 0 or 1
1

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector