Answer the question
In order to leave comments, you need to log in
How to make such a feint with ears with double?
Based on the contents of the memory, output a double value in exponential form: sm*2^{Sp}, where s is the sign of the mantissa, m is the mantissa, S is the sign of the exponent, p is the exponent of the number.
Examples:
Enter a number: -2.5
Result: -1.25*2^1
Enter a number: 12312.323
Result: +1.5029691162109375384*2^13
I know how to do this algorithmically, but I need to fetch this representation from memory. I heard something about using union in this case and casting to int64_t, but I didn’t quite understand how to apply it
Answer the question
In order to leave comments, you need to log in
Use memcopy. Copy from the address of a double variable to the address of an int variable.
Tricks with union and pointer reinterpretation are quite dangerous.
Why not? I write in C with crosses, but there is nothing specific there, except for a couple of reinsurances.
C++20 also introduced 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;
}
Something like this
union double_bitfld_t {
double dbl;
struct {
unsigned int mnt : 52;
unsigned int exp : 11;
unsigned int sgn : 1;
} bits;
};
double_bitfld_t x;
cin >> x.dbl;
cout << (x.bits.sgn ? '+' : '-') << (1+x.bits.mnt/double(1<<52)) << "*2^" << (x.bits.exp-1023) << endl;
Didn't find what you were looking for?
Ask your questionAsk a Question
731 491 924 answers to any question