#include <cstdint>

constexpr double pow2(std::int16_t e)
{
    return e == 0 ? 1. :
                    e > 0 ? 2. * pow2(std::int16_t(e - 1)) :
                    0.5 * pow2(std::int16_t(e + 1));
}

static_assert(pow2(0) == 1., "");
static_assert(pow2(1) == 2., "");
static_assert(pow2(10) == 1024., "");
static_assert(pow2(-1) == 0.5, "");
static_assert(pow2(-2) == 0.25, "");

template<bool S , std::int16_t E , std::uint32_t M>
struct number
{
    static constexpr const bool          sign     = S;
    static constexpr const std::int16_t  exponent = E;
    static constexpr const std::uint32_t mantissa = M;

    static constexpr const double value = (sign ? -1. : 1.) * M * pow2(E);
};

static_assert(number<false, 0, 42>::value == 42., "");
static_assert(number<false, 1, 3>::value == 6., "");
static_assert(number<false, 10, 2>::value == 2048., "");
static_assert(number<false, -1, 2>::value == 1., "");
static_assert(number<false, -2, 1>::value == 0.25, "");


int main() {
    return 0;
}
