У меня есть фреймворк, который использует 16-битные числа с плавающей запятой, и я хотел разделить его компоненты, чтобы затем использовать их для 32-разрядных операций с плавающей запятой. В моем первом подходе я использовал сдвиги битов и тому подобное, и хотя это работало, читать было дико хаотично.
Затем я хотел использовать вместо этого структуры с пользовательским размером в битах и использовать объединение для записи в эту структуру.
Код для воспроизведения вопроса:
#include <iostream>
#include <stdint.h>
union float16_and_int16
{
struct
{
uint16_t Mantissa : 10;
uint16_t Exponent : 5;
uint16_t Sign : 1;
} Components;
uint16_t bitMask;
};
int main()
{
uint16_t input = 0x153F;
float16_and_int16 result;
result.bitMask = input;
printf("Mantissa: %#010x\n", result.Components.Mantissa);
printf("Exponent: %#010x\n", result.Components.Exponent);
printf("Sign: %#010x\n", result.Components.Sign);
return 0;
}
В этом примере я ожидал бы, что моя Мантисса будет 0x00000054, показатель степени будет 0x0000001F, а знак 0x00000001
Вместо этого я получаю Мантиссу: 0x0000013f, Экспонент: 0x00000005, Знак: 0x00000000
Это означает, что из моей битовой маски сначала был взят Знак (первый бит), следующие 5 битов для экспоненты, затем 10 битов для мантиссы, так что порядок обратный тому, что я хотел. Почему это происходит?