This is a technique that allows us to store data inside a double by punning the value of a NaN. This is used inside javascript engines to represent all possible user types as a single NaN. This is well explained at the SpiderMonkey internals page

#include <assert.h>#include <iostream>#include <limits>using namespace std;// https://en.wikipedia.org/wiki/NaNunion PunDouble {    double d;    struct {        uint64_t m      : 51;        uint32_t qnan: 1;        uint32_t e      : 11;        uint32_t s      : 1;    } bits;    PunDouble(double d) : d(d) {};    PunDouble(uint32_t s, uint32_t e, uint64_t m) {        bits.s = s;        bits.e = e;        bits.qnan = 1;        bits.m = m;    }};union PunInt {    int32_t i;    uint32_t bits;    PunInt(int32_t i): i(i) {};};using namespace std;struct Box {    inline bool is_int() const {        auto pd = PunDouble(d);        return pd.bits.e == 0b11111111111 && pd.bits.qnan == 1;    }    inline bool isdouble() const {        auto pd = PunDouble(d);        return (pd.bits.e != 0b11111111111) || (pd.bits.qnan == 0);    }    int32_t get_int() const {        assert(is_int());        uint64_t m = PunDouble(d).bits.m; return PunInt(m).i;    }    double get_double() const { assert(isdouble()); return d; }    Box operator +(const Box &other) const;    static Box mk_int(int32_t i) {        return Box(PunDouble(1, 0b11111111111, PunInt(i).bits).d);    }    static Box mk_double(double d) { return Box(d); }    double rawdouble() const { return d; }    private:    double d; Box(double d) : d(d) {}};// = 64 bitsBox Box::operator + (const Box &other) const {    if (isdouble()) {        assert(other.isdouble());        return Box::mk_double(d + other.d);    }    else {        assert(is_int());        assert(other.is_int());        return Box::mk_int(get_int() + other.get_int());    }}ostream &operator << (ostream &o, const Box &b) {    if (b.isdouble()) { return o << "[" << b.get_double() << "]"; }    else { return o << "[" << b.get_int() << "]"; }}int32_t randint() { return (rand() %2?1:-1) * (rand() % 100); }int32_t main() {    // generate random integers, check that addition checks out    srand(7);    for(int32_t i = 0; i < 1000; ++i) {        const int32_t i1 = randint(), i2 = randint();        const Box b1 = Box::mk_int(i1), b2 = Box::mk_int(i2);        cout << "i1:" << i1 << "  b1:" << b1 << "  b1.double:" << b1.rawdouble() << "  b1.get_int:" << b1.get_int() << "\n";        cout << "i2:" << i2 << "  b2:" << b2 << "  b2.double:" << b2.rawdouble() << "  b2.get_int:" << b2.get_int() << "\n";        assert(b1.is_int());        assert(b2.is_int());        assert(b1.get_int() == i1);        assert(b2.get_int() == i2);        Box b3 = b1 + b2;        assert(b3.is_int());        assert(b3.get_int() == i1 + i2);    }    for(int32_t i = 0; i < 1000; ++i) {        const int32_t p1 = randint(), q1=randint(), p2 = randint(), q2=randint();        const double d1 = (double)p1/(double)q1;        const double d2 = (double)p2/(double)q2;        const Box b1 = Box::mk_double(d1);        const Box b2 = Box::mk_double(d2);        cout << "d1: " << d1 << " | b1: " << b1 << "\n";        cout << "d2 " << d2 << " | b2: " << b2 << "\n";        assert(b1.isdouble());        assert(b2.isdouble());        assert(b1.get_double() == d1);        assert(b2.get_double() == d2);;        Box b3 = b1 + b2;        assert(b3.isdouble());        assert(b3.get_double() == d1 + d2);    }    return 0;}