I am using .str(n, std::ios_base::scientific) to print ccp_dec_floats.
I've noticed that it rounds up.
I am using cpp_dec_float for accounting, so I need to round downward. How can this be done?
It doesn't round up. In fact, it does banker's round: See it Live On Coliru
#include <boost/multiprecision/number.hpp>
#include <boost/multiprecision/cpp_int.hpp>
#include <boost/multiprecision/cpp_dec_float.hpp>
#include <iostream>
namespace mp = boost::multiprecision;
int main()
{
using Dec = mp::cpp_dec_float_50;
for (Dec d : {
Dec( "3.34"), Dec( "3.35"), Dec( "3.38"),
Dec( "2.24"), Dec( "2.25"), Dec( "2.28"),
Dec("-2.24"), Dec("-2.25"), Dec("-2.28"),
Dec("-3.34"), Dec("-3.35"), Dec("-3.38"),
})
{
std::cout << d.str(2, std::ios_base::fixed)
<< " -> " << d.str(1, std::ios_base::fixed) << "\n";
}
}
Prints:
3.34 -> 3.3
3.35 -> 3.4
3.38 -> 3.4
2.24 -> 2.2
2.25 -> 2.2
2.28 -> 2.3
-2.24 -> -2.2
-2.25 -> -2.2
-2.28 -> -2.3
-3.34 -> -3.3
-3.35 -> -3.4
-3.38 -> -3.4
So if you want another kind of rounding, you'd want to write it explicitly
Here's a generic approach (Live On Coliru)
template <int decimals = 0, typename T>
T round_towards_zero(T const& v)
{
static const T scale = pow(T(10), decimals);
if (v.is_zero())
return v;
// ceil/floor is found via ADL and uses expression templates for optimization
if (v<0)
return ceil(v*scale)/scale;
else
// floor is found via ADL and uses expression templates for optimization
return floor(v*scale)/scale;
}
which hopefully compiles down to optimal code due to statically known scale factor and the use of expression templates in Boost Multiprecision library.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With