Search code examples
c++boostmodulusarbitrary-precision

Boost cpp_dec_float supports modulus operation


As the title says, does Boost's cpp_dec_float support modulus operations? I'm dealing with money and would like to do some modulus operations to get the number of bills and coins that I need to return. cpp_dec_float seems to be the only arbitrary precision class that supports base 10.


Solution

  • If all you want is coin distribution, can't you just do it without modulo?

    Boost multiprecision does define fmod, trunc, mod etc. whenever possible for a backend type; Here's a working demo: Live On Coliru

    #include <boost/multiprecision/cpp_dec_float.hpp>
    #include <boost/multiprecision/number.hpp>
    #include <iostream>
    
    using Num = boost::multiprecision::number<boost::multiprecision::cpp_dec_float<128>>;
    
    int main()
    {
        Num x("189.5307");
    
        for (Num denom : { 
                Num("500.00"),   Num("200.00"),   Num("100.00"),
                 Num("50.00"),    Num("20.00"),    Num("10.00"),
                  Num("5.00"),     Num("2.00"),     Num("1.00"),
                  Num("0.50"),     Num("0.20"),     Num("0.10"),
                  Num("0.05"),     Num("0.02"),     Num("0.01"),
            })
        {
            Num count = x/denom;
    
            if (count >= 1)
            {
                count = trunc(count);
                std::cout << count << " * " << std::right << std::setw(6) << denom.str(2, std::ios::fixed) << "\n";
                x -= denom * count;
            }
        }
    
        std::cout << "Remainder: " << x << "\n";
    }
    

    I explicitly selected an "invalid" input value (one with excess precision for the denominations) so you can verify it handles them. I have not bothered with the case for negative amounts, but you can figure that out :)

    1 * 100.00
    1 *  50.00
    1 *  20.00
    1 *  10.00
    1 *   5.00
    2 *   2.00
    1 *   0.50
    1 *   0.02
    1 *   0.01
    Remainder: 0.0007