printf("%.3lf\n", -0.0001);
This outputs -0.000, but shouldn't it be 0.000?
How can I make this print without the minus sign, i.e. 0.000 ?
printf("%.3lf\n", -0.0001);
This outputs -0.000, but shouldn't it be 0.000?
How can I make this print without the minus sign, i.e. 0.000 ?
On
C++ inherits printf from C. In C11 standard §7.21.6.1 The fprintf function, the footnote says:
The results of all floating conversions of a negative zero, and of negative values that round to zero, include a minus sign.
On
The float representation ( https://en.wikipedia.org/wiki/Floating_point) has a sign bit. Who implemented the printf decided to explicitly put it there even when all the printed numbers are 0.
On
EDIT: My previous solution didn't solve the problem as it should.
template <int precision=0, double(*round_func)(double)=std::round>
double round(double a)
{
auto multiplier = std::pow(10, precision);
a *= multiplier;
a = round_func(a);
if (a == 0.0) return 0.0;
a /= multiplier;
return a;
}
int main()
{
printf("printf: %.3lf\n", -0.0001);
printf("round : %.3lf\n", round<3>(-0.0001));
system("PAUSE");
}
Result: printf: -0.000 round : 0.000
Comparing printf w/ precision and round
int main()
{
printf("printf: %05.2lf\n", 12345.6789);
printf("printf: %05.2lf\n", 12345.1234);
printf("\n");
printf("round : %05.2lf\n", round<2, std::round>(12345.6789));
printf("round : %05.2lf\n", round<2, std::round>(12345.1234));
printf("\n");
printf("floor : %05.2lf\n", round<2, std::floor>(12345.6789));
printf("floor : %05.2lf\n", round<2, std::floor>(12345.1234));
printf("\n");
printf("ceil : %05.2lf\n", round<2, std::ceil>(12345.6789));
printf("ceil : %05.2lf\n", round<2, std::ceil>(12345.1234));
system("PAUSE");
}
Result:
printf: 12345.68
printf: 12345.12
round : 12345.68
round : 12345.12
floor : 12345.67
floor : 12345.12
ceil : 12345.68
ceil : 12345.13
So printf seems to also round values when using precision.
You might use this to round your answer before printing it:
template <int precision>
double round(double a)
{
auto multiplier = std::pow(10, precision);
a *= multiplier;
a = std::round(a);
a /= multiplier;
return a;
}
Alternatively, if you just want to cut of the rest:
template <int precision>
double round_down(double a)
{
auto multiplier = std::pow(10, precision);
a *= multiplier;
a = std::floor(a);
a /= multiplier;
return a;
}
This works even with a negative precision:
int main()
{
//Round at precision
printf("%5.4lf\n", round<4>(12345.6789)); //Output = 12345.6789
printf("%5.4lf\n", round<3>(12345.6789)); //Output = 12345.6790
printf("%5.4lf\n", round<2>(12345.6789)); //Output = 12345.6800
printf("%5.4lf\n", round<1>(12345.6789)); //Output = 12345.7000
printf("%5.4lf\n", round<0>(12345.6789)); //Output = 12346.0000
printf("%5.4lf\n", round<-1>(12345.6789)); //Output = 12350.0000
printf("%5.4lf\n", round<-2>(12345.6789)); //Output = 12300.0000
printf("%5.4lf\n", round<-3>(12345.6789)); //Output = 12000.0000
printf("%5.4lf\n", round<-4>(12345.6789)); //Output = 10000.0000
printf("%5.4lf\n", round<-5>(12345.6789)); //Output = 0.0000
//Cut off/Round down after precision
printf("%5.4lf\n", round_down<4>(12345.6789)); //Output = 12345.6789
printf("%5.4lf\n", round_down<3>(12345.6789)); //Output = 12345.6780
printf("%5.4lf\n", round_down<2>(12345.6789)); //Output = 12345.6700
printf("%5.4lf\n", round_down<1>(12345.6789)); //Output = 12345.6000
printf("%5.4lf\n", round_down<0>(12345.6789)); //Output = 12345.0000
printf("%5.4lf\n", round_down<-1>(12345.6789)); //Output = 12340.0000
printf("%5.4lf\n", round_down<-2>(12345.6789)); //Output = 12300.0000
printf("%5.4lf\n", round_down<-3>(12345.6789)); //Output = 12000.0000
printf("%5.4lf\n", round_down<-4>(12345.6789)); //Output = 10000.0000
printf("%5.4lf\n", round_down<-5>(12345.6789)); //Output = 0.0000
}
Alternative solution, that allows defining the method of rounding:
template <int precision=0, double(*round_func)(double)=std::round>
double round(double a)
{
auto multiplier = std::pow(10, precision);
a *= multiplier;
a = round_func(a);
a /= multiplier;
return a;
}
int main()
{
printf("%05.4lf\n", round(12345.6789)); //Output = 12345.0000
printf("%05.4lf\n", round<1>(12345.6789)); //Output = 12345.7000
printf("%05.4lf\n", round<1, std::round>(12345.6789)); //Output = 12345.7000
printf("%05.4lf\n", round<1, std::floor>(12345.6789)); //Output = 12345.6000
printf("%05.4lf\n", round<1, std::ceil>(12345.6789)); //Output = 12345.7000
}
The correct answer has already been given. Just wanted to add that you'll get the same from c++ cout
If you want to get rid of the sign, it can be done like this:
output:
EDIT Could this be done without converting to string?
How about:
output:
so it seems to work!
But it won't work for all rounding modes.
Therefore it seems safer to use the first version with string convert.