1

I am utterly baffled as to how one should actually accomplish this, I have mostly managed to get my code to work until I try to run ceil() on a cpp_dec_float<0> type at which point it will explode on me and refuse to cooperate, after careful examination of boost documentation and google searching I have concluded that I cannot locate the answer on my own, thus I turn here to ask for help from infinitely more competent programmers.

#include <iostream>
#include <boost/multiprecision/cpp_int.hpp>
#include <boost/multiprecision/cpp_dec_float.hpp>
#include <boost/math/special_functions/pow.hpp>
#include <boost/chrono/ceil.hpp>
#include <boost/multiprecision/number.hpp>

namespace mp = boost::multiprecision;
using namespace std;
using namespace boost::math;
using namespace boost::chrono;
using Int = mp::cpp_int;
Int reward(Int baseReward, int percent);

int main(int argc, char** argv)
{

    reward = calcReward(immBase, percent);
    return 0;
}

Int calcReward(Int baseReward, int percent)
{
    using Dec  = mp::number<mp::cpp_dec_float<0>>;
    Dec mult   = 0.1+0.01*percent;
    Dec five   = 5;
    Dec base   = baseReward.convert_to<Dec>();
    Int result = ceil(five*base*mult);

    return result;
}

that's the code when stripped from unnecessary junk, the five variable is a dirty hack to get it to accept the multiplication with the arbitrary precision floating point value (as it just decided to say that there's no matching operator * otherwise). This is rather bemusing and quite frustrating, ceil().convert_to() didn't work either and spat out an arbitrary undecipherable error. (template errors are unreadable)

this code does require the -std=c++11 flag when compiling, as is probably obvious.

  • https://www.livecoding.tv/sehe/ – sehe Aug 25 '15 at 20:14
  • 1
    In case you like a peek in the kitchen: https://www.livecoding.tv/video/boost-multiprecision-et-eval-and-conversions/ ([experiment](http://chat.stackoverflow.com/transcript/10?m=24182469#24182469)) – sehe Aug 25 '15 at 20:30

1 Answers1

1

The usual culprit is that the result of BMP expressions are not their target types, but still "lazy" expression templates, and they don't have all the implicit conversions. So, you need to evaluate these "manually" (explicitly):

return Dec(ceil(five*base*mult)).convert_to<Int>();

See it Live On Coliru

#include <iostream>
#include <boost/multiprecision/detail/default_ops.hpp>
#include <boost/multiprecision/cpp_int.hpp>
#include <boost/multiprecision/cpp_dec_float.hpp>
#include <boost/math/special_functions/pow.hpp>
#include <boost/multiprecision/number.hpp>

namespace mp = boost::multiprecision;

using Int = mp::cpp_int;

Int calcReward(Int baseReward, int percent);

int main()
{
    Int const immBase = 400;
    int const percent = 12;

    std::cout << calcReward(immBase, percent);
}

Int calcReward(Int baseReward, int percent)
{
    using Dec  = mp::cpp_dec_float_50;
    Dec mult   = 0.1+0.01*percent;
    Dec five   = 5;
    Dec base   = baseReward.convert_to<Dec>();

    return Dec(ceil(five*base*mult)).convert_to<Int>();
}

Notes:

Community
  • 1
  • 1
sehe
  • 374,641
  • 47
  • 450
  • 633
  • what potential drawbacks would disabling expression templates have? Speed isn't really of any great concern, it's a throwaway thing that only calculates one singular equation for me, regardless both solutions seem to be simple enough. –  Aug 26 '15 at 14:09
  • okay, so I couldn't get the expression template option to work (although I didn't try very hard), but the solution you recommended did work, thank you very much for your help. –  Aug 26 '15 at 14:20
  • I did however notice something of rather peculiar interest, when inputting large numbers (150 or so) it'll throw, what(): Unexpected content found while parsing character string. This would imply that boost does not enjoy integral to floating point with very large numbers. (even though it's arbitrary precision numbers) –  Aug 26 '15 at 14:43
  • Perhaps you should post that as its own question – sehe Aug 26 '15 at 14:45
  • I will if I can't figure out a solution myself, but for now I'm taking it as a challenge, I don't ask unless I've at least tried first. –  Aug 26 '15 at 14:47
  • and fixed, I switched to the mpfr backend... only problem is that my test calculation would need something in the order of 451GB of ram but at least it works (test calculation is far larger than I'll actually need, some 6 orders of magnitude larger specifically) –  Aug 26 '15 at 15:05