преобразование double в int64_t с++
int64_t a = *(int64_t *)&x;
почему после данной строки а становится равным -4661117527937406468 при double х=-0.001, понятно, что мы начинаем работать со значением переменной x в типе данных int64_t, но что происходит именно при конвертировании, получается ведь -4661117527937406468 в бинарном представлении равно -0.001?
Ответы (1 шт):
Автор решения: Stanislav Volodarskiy
→ Ссылка
Число двойной точности: такой формат у double
, если значение конечное и не равно нулю. Старший бит - знак. Дальше одиннадцать бит - экспонента (e). Остальные биты - мантисса (m).
Чтобы собрать число из кусков, надо посчитать (1 + m/252)×2e-1023. Потом ставите знак и готово:
#include <cstring>
#include <iostream>
int main() {
double d;
std::cin >> d;
int64_t n;
static_assert(sizeof n == sizeof d);
// это правильный способ приводить значения
// компилятор превращает это в одну инструкцию копирования,
// никаких вызовов функций
std::memcpy(&n, &d, sizeof d);
std::cout << n << '\n';
auto sign = (n >> 63) & 1;
auto exponent = (n >> 52) & ((1LL << 11) - 1);
auto mantissa = n & ((1LL << 52) - 1);
std::cout << sign << ' ' << exponent << ' ' << mantissa << '\n';
double d2 = 1. + double(mantissa) / double(1LL << 52);
for (int i = 1023; i < exponent; ++i) {
d2 *= 2;
}
for (int i = 1023; i > exponent; --i) {
d2 /= 2;
}
if (sign == 1) {
d2 = -d2;
}
std::cout << d2 << '\n';
}
$ g++ format.cpp $ echo -0.001 | ./a.out -4661117527937406468 1 1013 108086391056892 -0.001