#include <iostream>
#include <cstring>
#include <bitset>
using namespace std;
int main()
{
double tx = 0xFFFF0000FFFF0000;
uint64_t tx1 = 0;
static_assert(sizeof(double) == sizeof(uint64_t));
memcpy(&tx1, &tx, sizeof(double));
bitset<64> b1(tx1);
cout << b1 << endl;
return 0;
}
Как я и ожидал, tx1
должен быть 0xFFFF0000FFFF0000.
но b1
дает 0x43EFFFE0001FFFE0.
Я хотел бы знать, как сделать b1
равным 0xFFFF0000FFFF0000.
Аппаратное двоичное представление значений, использующих разные типы, отличается. Я думаю, что некоторые программы также используют разные двоичные представления для работы с разными числовыми типами; типы с плавающей запятой и целочисленные типы. На ум пришел другой тип… комплексные числа, однако C++ изначально не поддерживает комплексные числа. Я думаю, теперь вы поняли.
Я беру это обратно. C++ поддерживает комплексные числа через стандартную библиотеку. Тем не менее, он использует другое двоичное представление.
@ChukwujiobiCanon «однако C++ изначально не поддерживает комплексные числа» - как вы тогда называете std::complex, если не «родной»?
0xFFFF0000FFFF0000
— это некоторое целочисленное значение, но важно отметить, что double
шириной 64 бита может представлять только целые числа до 53 бит. После этого вы просто получите самое близкое приближение.
Когда это произойдет, у вас появится объект double
, значение которого близко, но не совсем к 0xFFFF0000FFFF0000
.
Затем вы std::memcpy
представляете double
обратно в целое число, но поскольку двойного числа больше нет 0xFFFF0000FFFF0000
, то и ваше целое число не изменится.
Еще следует отметить, что типы с плавающей запятой и целочисленные типы имеют разные двоичные представления. 42 в double
не имеет того же двоичного представления, что и 42
в uint64_t
. Это значит, что; несмотря ни на что, вы никогда не получите ту же самую битовую комбинацию обратно в результате операции.
Единственное, что вы можете сделать, это использовать memcpy
в обоих направлениях.
uint64_t start = 0xFFFF0000FFFF0000;
double tx;
uint64_t tx1;
memcpy(&tx, &start, sizeof(start));
// now `tx` is some value but it has the binary representation of 0xFFFF0000FFFF0000
memcpy(&tx1, &tx, sizeof(tx));
// now tx1 has the binary representation of 0xFFFF0000FFFF0000 since the bits never get changed
Большое спасибо. Могу я спросить еще одну вещь? Не могли бы вы порекомендовать метод копирования двоичного представления double в переменную uint64_t??
@Handrix У тебя это уже есть. memcpy(&tx1, &tx, sizeof(double));
хранит двоичное представление того, во что было преобразовано целое число 0xFFFF0000FFFF0000
, когда оно было сохранено в double
. Вот почему я сказал, что оно никогда не будет соответствовать целочисленному представлению. Двоичное представление 42
различается для типов с плавающей запятой и целочисленных типов.
@Handrix, кажется, ты путаешь значение double со значением необработанных байтов. Вы можете посмотреть, например, здесь h-schmidt.net/FloatConverter/IEEE754.html, чтобы увидеть разницу.
Я очень ценю вашу помощь. это очень полезно.
bitset<64> b1(0xFFFF0000FFFF0000);
сделает то, что вы попросите. Боюсь, это на самом деле не отвечает на ваш вопрос, но неясно, почему. Какова цель кода? мне интересно