The cmath
library ( math.h
for those coming from C), has a trunc
function that allows you to truncate a float
or a double
. The truncation function eliminates the decimal part of the number. To eliminate a certain number of decimals you can choose to temporarily include those decimals in the whole part of the number, apply truncated and reposition them as decimals:
#include <cmath>
#include <iomanip>
#include <iostream>
int main()
{
float numero = 1.57;
std::cout << std::fixed << std::setprecision(1) << std::trunc(numero*10)/10;
}
Example in wandbox
This can be left more nice if we divide the code into functions:
constexpr double Exp(int numero)
{
return ( numero <= 0 )? 1 : 10 * Exp(numero-1);
}
double Truncar(double numero, int decimales)
{
return std::trunc(numero*Exp(decimales))/Exp(decimales);
}
void ImprimirDouble(double numero, int decimales)
{
std::cout << std::fixed << std::setprecision(decimales) << Truncar(numero,decimales) << '\n';
}
int main()
{
double numero = 3.777;
ImprimirDouble(numero,0);
ImprimirDouble(numero,1);
ImprimirDouble(numero,2);
}
Example in wandbox
Although I personally like more the option of giving a strong typing to the variable ... the code is cleaner. The example can be abstracted with templates and so on, but I think that it would lose the focus of what I'm trying to teach:
namespace MathUtils
{
constexpr double Exp(int numero)
{
return ( numero <= 0 )? 1 : 10 * Exp(numero-1);
}
double Truncar(double numero, int decimales)
{
return std::trunc(numero*Exp(decimales))/Exp(decimales);
}
}
class Double
{
double value;
public:
explicit Double(double value)
: value(value)
{ }
operator double() const
{ return value; }
friend std::ostream& operator<<(std::ostream& os, Double const& value);
};
std::ostream& operator<<(std::ostream& os, Double const& value)
{
auto precision = os.precision();
return os << std::fixed << MathUtils::Truncar(value,precision);
}
int main()
{
Double numero(3.777);
std::cout << std::setprecision(0) << numero << '\n';
std::cout << std::setprecision(1) << numero << '\n';
std::cout << std::setprecision(2) << numero << '\n';
}
Example in wandbox
This solution has several advantages:
- The output to the console or file is more natural.
- Having a strong typing prevents unwanted conversions.
- The code is much more expressive. It may not be appreciated in this example but on a larger scale it is seen quickly.