Search code examples
boost

Recommended way to cast a boost cpp_int to a double?


I have some code were I avoid some costly divisions by converting a boost integer to a double. For the real code I will build an fp type that's big enough to hold the maximal value (exponent). To test I am using a double. So I do this:

#define NTYPE_BITS 512
typedef number<cpp_int_backend<NTYPE_BITS, NTYPE_BITS, unsigned_magnitude, unchecked, void> > NTYPE;
NTYPE a1 = BIG_VALUE;
double a1f = (double)a1;

The code generated for that cast is quite complicated. I see it's basically looping over all the values in a1 (least significant first) scaling them by powers of two. Now in this case I guess at most the number of elements that could affect the result are the last two (64 bits for each element and the most significant element might have less that 64 bits used). Is there a better way to do this?


Solution

  • First off, NEVER use C-Style casts. (Why use static_cast<int>(x) instead of (int)x?). Second, avoid using namespace. (Third, reserve all-caps names for macros).

    That said:

    double a1f = a1.convert_to<double>();
    

    Is your ticket.

    Live On Coliru

    #include <boost/multiprecision/cpp_int.hpp>
    #include <iostream>
    namespace bmp = boost::multiprecision;
    
    //0xDEADBEEFE1E104B1D00008BADF00D000ABADBABE000D15EA5E
    #define BIG_VALUE "0xDEADBEEFE1E104B1D00008BADF00D000ABADBABE000D15EA5E"
    #define NTYPE_BITS 512
    
    int main() {
        using NTYPE = bmp::number<
            bmp::cpp_int_backend<
                NTYPE_BITS, NTYPE_BITS,
                bmp::unsigned_magnitude, bmp::unchecked, void>>;
    
        NTYPE a1(BIG_VALUE);
    
        std::cout << a1 << "\n";
        std::cout << std::hex << a1 << "\n";
        std::cout << a1.convert_to<double>() << "\n";
    }
    

    Prints

    1397776821048146366831161011449418369017198837637750820563550
    deadbeefe1e104b1d00008badf00d000abadbabe000d15ea5e
    1.39778e+60