Можно ли double "засунуть" в bitset, чтобы он вывел его в 2виде?

276
06 июня 2022, 18:30

Можно ли double "засунуть" в bitset, чтобы он вывел его в 2виде?

Написал код, что-то не очень получается:

double number = 123.456;
unsigned long long bits = *reinterpret_cast<unsigned long long*>(&number);
cout << "Double: " << bits << endl;
cout << "Size Double: " << sizeof(bits) << endl;
bitset<sizeof(bits)> bitset_number{bits};
cout << "Binary: " << bitset_number << endl;
cout << "Dec: " << bitset_number.to_ulong() << endl;
Answer 1

Думаю, хочется где то такого

double a = 1.5; 
auto b = std::bitset<64>(*(unsigned long long*)(&a));
std::cout << b << '\n';
// вывод 0011111111111000000000000000000000000000000000000000000000000000
b.set(63); // поправим знаковый бит, должно получится -1.5
std::cout << b << '\n';
// вывод 1011111111111000000000000000000000000000000000000000000000000000
unsigned long long c = b.to_ullong();
std::cout << (*(double*)(&c)) << '\n';
// вывод -1.5

Поиграться и убедится в правильности можно здесь https://evanw.github.io/float-toy/

update

я ввел 12.15, а оно выдает не то.

Все оно то выдает, просто нужно "увидеть". При 12.15 будет вывод

0100000000101000010011001100110011001100110011001100110011001101
+ экспон.   ^ это начинается число (мантиса).

ещё не видно? закроем глаза на экспоненту (это первые 12 символов), Получаем 1000010011001100110011001100110011001100110011001101.

Потом смотрим в формат числа и понимаем, что так как любое не нулевое число всегда будет содержать 1 в самом начале, то там на самом деле записано 11000010011001100110011001100110011001100110011001101

Сравним это с 1100.00100110011 (и не забываем, что здесь на самом деле надо писать так 1100.00(1001) - это периодическая дробь!), то видим, что это одно в одно.

Осталось понять, где точку ставить. а в этом нам экспонента поможет. Она у нас 10000000010. Самый левый единичный бит - это знак, но наоборот. в данном случае это плюс. и получается степень 2 в 4. То есть, точку нужно поставить после 4 символа в записи. С отрицательными степенями там чуточку сложнее, но тоже решаемо.

Подсуммируем. Вам нужно просто написать аккуратно вывод и всех делов то.

Ещё почитать https://docs.microsoft.com/ru-ru/cpp/build/ieee-floating-point-representation?view=msvc-160

upd

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

double a = 1.5;
unsigned long long bx = 0;
// убедимся, что у нас они одинакового размера.
static_assert(sizeof(a) == sizeof(bx), "sizeof(double) == sizeof(ull)");
// скопируем. Умные компиляторы могут сделать этот код не хуже сишного каста
std::memcpy(&bx, &a, sizeof(bx));
// а дальше уже по классике
auto b = std::bitset<64>(bx);
Answer 2

Для начала: весь ваш код можно заменить на cout << std::bitset<64>(number); и будет взят целая часть числа. А теперь попробуем разобраться как получать все число.

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

const double number = 123.456, 
     exp = 3,
     e = pow(10, exp);  
std::bitset<64> b(number * e);
unsigned long n = b.to_ullong();
cout << b << '\n' 
    << n << "e-" << exp;
//получить число с плавающей точкой
cout << "\noriginal number:  " << (double)n / e;
Answer 3

0100000000101000010011001100110011001100110011001100110011001101

+экспонента__^ мантисса

READ ALSO
Отображение переменных в QtCreator через gdb

Отображение переменных в QtCreator через gdb

Отладчик gdb не показывает содержимое переменной типа std::string

269
С++ - Вызвано исключение по адресу 0x00502974

С++ - Вызвано исключение по адресу 0x00502974

После вписывания массива пишет - Вызвано исключение по адресу 0x00502974 в Project2exe: 0xC0000005: нарушение прав доступа при чтении по адресу 0xFDFDFE01

188
Fatal error: Uncaught PDOException: SQLSTATE[42000]: Syntax error or access violation: 1064

Fatal error: Uncaught PDOException: SQLSTATE[42000]: Syntax error or access violation: 1064

You have an error in your SQL syntax; 'BY sort_order ASC' at line 1 in C:\xampp\htdocs\models\Categoryphp:12

284