Force cpp_dec_float d'arrondir à la baisse
-
21-12-2019 - |
Question
Je suis à l'aide de .str(n, std::ios_base::scientific)
pour imprimer ccp_dec_float
s.
J'ai remarqué qu'il arrondit.
Je suis à l'aide de cpp_dec_float
pour la comptabilité, donc j'ai besoin d'arrondir à la baisse.Comment cela peut-il être fait?
La solution
Il n'a pas de round up.En fait, il n'banquier tour:Voir En Direct Sur 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";
}
}
Impressions:
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
Donc, si vous souhaitez un autre type d'arrondi, vous voulez l'écrire explicitement
Voici une approche générique (En Direct Sur 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;
}
qui, espérons-le compile vers le bas pour un code optimal en raison de statiquement connu facteur d'échelle et l'utilisation de l'expression de modèles dans Boost Multiprecision de la bibliothèque.
Autres conseils
Je suppose que vous essayez d'atteindre en l'arrondissant à un certain point décimal, correct?
Standard arrondissement
double rounding_func(double in, double precision){
return round(in*pow(10,precision))/pow(10,precision);
}
Mais comme ton titre l'indique, vous essayez de le forcer à tour vers le bas, de sorte envisager de
double rounding_func(double in, double precision){
return floor(in*pow(10,precision))/pow(10,precision);
}
Bonne chance!