Почему нельзя? Пишу на Си с крестами, но там ничего специфичного нет, кроме парочки перестраховок.
В Си++20 появился ещё и bit_cast.
#include <iostream>
union DoubleInt {
double asDouble;
uint64_t asInt;
};
static_assert(sizeof(double) == sizeof(uint64_t), "Strange machine with double != int64");
constexpr int BITS_MANTISSA = 52;
constexpr int BITS_EXPONENT = 11;
constexpr int BITS_SIGN = 1;
static_assert(BITS_MANTISSA + BITS_EXPONENT + BITS_SIGN == 64, "Programmer's funkup");
constexpr uint64_t MANTISSA_UNIT = uint64_t(1) << BITS_MANTISSA;
constexpr uint64_t MANTISSA_MASK = MANTISSA_UNIT - 1;
constexpr int EXPONENT_SHIFT = BITS_MANTISSA;
constexpr uint64_t EXPONENT_MAX = (uint64_t(1) << BITS_EXPONENT) - 1;
constexpr uint64_t EXPONENT_ORIGIN = EXPONENT_MAX >> 1;
constexpr uint64_t EXPONENT_MASK = EXPONENT_MAX << EXPONENT_SHIFT;
constexpr uint64_t EXPONENT_SHIFTED_ORIGIN = EXPONENT_ORIGIN << EXPONENT_SHIFT;
constexpr int SIGN_SHIFT = BITS_MANTISSA + BITS_EXPONENT;
constexpr uint64_t SIGN_MASK = uint64_t(1) << SIGN_SHIFT;
int main()
{
DoubleInt x { -3.45 };
// Простите уж, без денормализованных чисел
// Оставим знак и мантиссу
DoubleInt xMantissa = x;
xMantissa.asInt &= (MANTISSA_MASK | SIGN_MASK);
// И добавим туда стандартный нулевой порядок
xMantissa.asInt |= EXPONENT_SHIFTED_ORIGIN;
// Извлечём порядок
int exponent = ((x.asInt & EXPONENT_MASK) >> EXPONENT_SHIFT) - EXPONENT_ORIGIN;
std::cout << xMantissa.asDouble << "*2^" << exponent << std::endl;
return 0;
}