Search code examples
c++boostboost-multiprecision

Boost multiprecision cpp_int multiplied by a float


It is possible to multiply a boost multiprecision int by a floating point number? Is this is not supported?

using bigint = boost::multiprecision::number<boost::multiprecision::cpp_int_backend<>>;

boost::multiprecision::bigint x(12345678); 
auto result = x * 0.26   // << THIS LINE DOES NOT COMPILE

Solution

  • No that's not supported because it is lossy.

    You can do the conversion explicitly:

    Live On Coliru

    #include <boost/multiprecision/cpp_int.hpp>
    #include <boost/multiprecision/cpp_dec_float.hpp>
    
    //using bigint = boost::multiprecision::number<boost::multiprecision::cpp_int_backend<>>;
    using bigint   = boost::multiprecision::cpp_int;
    using bigfloat = boost::multiprecision::cpp_dec_float_50;
    
    int main() {
        bigint x(12345678); 
        bigfloat y("0.26");
        std::cout << "x: " << x << "\n";
        std::cout << "y: " << y << "\n";
        bigfloat result = x.convert_to<bigfloat>() * y;
    
        //bigint z = result; // lossy conversion will not compile
        bigint z1 = static_cast<bigint>(result);
        bigint z2 = result.convert_to<bigint>();
    
        std::cout << "Result: " << result << "\n";
        std::cout << "z1: " << z1 << "\n";
        std::cout << "z2: " << z2 << "\n";
    }
    

    Prints

    x: 12345678
    y: 0.26
    Result: 3.20988e+06
    z1: 3209876
    z2: 3209876
    

    CAVEAT

    A common pitfall are lazily-evaluated expression templates. They're a trap when using temporaries:

    auto result = x.convert_to<bigfloat>() * bigfloat("0.26");
    

    Using result thereafter is Undefined Behaviour, because the temporaries have been destroyed. Assigning to bigfloat forces the evaluation.