Могу ли я напечатать -0.000 как 0.000?

printf("%.3lf\n", -0.0001);

Это выводы -0.000но не должно быть 0.000?

Как сделать этот отпечаток без знака минус, т.е. 0.000 ?

1

Решение

Правильный ответ уже дан. Просто хотел добавить, что вы получите то же самое от c ++ cout

Если вы хотите избавиться от знака, это можно сделать так:

double fixSign(double d)
{
std::ostringstream strs;
strs << std::fixed << std::setprecision(3) << d;
std::string str = strs.str();

if (str == "-0.000") return 0.0;

return d;
}

int main()
{
double d=-0.0001;

printf("%.3lf\n", d);

cout << std::fixed << std::setprecision(3) << d << endl;

cout << std::fixed << std::setprecision(3) << fixSign(d) << endl;

return 0;
}

выход:

-0.000
-0.000
0.000

РЕДАКТИРОВАТЬ
Может ли это быть сделано без преобразования в строку?

Как насчет:

#define PRE 3
#define LIMIT -0.0005  // Must have PRE zeros after the decimal point

// VERSION WITHOUT USE OF STRING
double fixSign_v2(double d)
{
if ((d < 0) && (d > LIMIT)) return 0;

return d;
}

double fixSign(double d)
{
std::ostringstream strs;
strs << std::fixed << std::setprecision(PRE) << d;
std::string str = strs.str();

if (str == "-0.000") return 0.0;

return d;
}

int main()
{
// PRE == 2
//double d1=-0.005;
//double d2=-0.0049999999999;

// PRE == 3
double d1=-0.0005;
double d2=-0.000499999999999;

// PRE == 10
//double d1=-0.00000000005;
//double d2=-0.0000000000499999999;

cout << std::fixed << std::setprecision(PRE+20) << d1 << endl;

cout << std::fixed << std::setprecision(PRE) << fixSign(d1) << endl;

cout << std::fixed << std::setprecision(PRE) << fixSign_v2(d1) << endl;

cout << "------------------------" << endl;

cout << std::fixed << std::setprecision(PRE) << d2 << endl;

cout << std::fixed << std::setprecision(PRE) << fixSign(d2) << endl;

cout << std::fixed << std::setprecision(PRE) << fixSign_v2(d2) << endl;

return 0;
}

выход:

-0.001
-0.001
-0.001
------------------------
-0.000
0.000
0.000

так что похоже на работу!

Но это не будет работать для всех режимов округления.

Поэтому кажется более безопасным использовать первую версию со строковым преобразованием.

1

Другие решения

C ++ наследует printf от C. В стандарте C11 §7.21.6.1 fprintf функция, сноска говорит:

Результаты всех плавающих преобразований отрицательного нуля и отрицательных значений, которые округляются до нуля,
включить знак минус.

6

Поплавковое представление ( https://en.wikipedia.org/wiki/Floating_point) имеет бит знака. Кто реализовал printf, решил явно поместить его туда, даже когда все напечатанные числа равны 0.

1

РЕДАКТИРОВАТЬ: Мое предыдущее решение не решило проблему должным образом.

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");
}

Результат:
printf: -0.000
раунд: 0,000

Сравнение printf с точностью и круглостью

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");
}

Результат:

printf: 12345.68
printf: 12345.12

round : 12345.68
round : 12345.12

floor : 12345.67
floor : 12345.12

ceil  : 12345.68
ceil  : 12345.13

Таким образом, printf, кажется, также округляет значения при использовании точности.

—————————

Старый ответ, пожалуйста, игнорируйте:

Вы можете использовать это, чтобы округлить свой ответ перед печатью:

template <int precision>
double round(double a)
{
auto multiplier = std::pow(10, precision);
a *= multiplier;
a = std::round(a);
a /= multiplier;
return a;
}

В качестве альтернативы, если вы просто хотите сократить остальное:

template <int precision>
double round_down(double a)
{
auto multiplier = std::pow(10, precision);
a *= multiplier;
a = std::floor(a);
a /= multiplier;
return a;
}

Это работает даже с отрицательной точностью:

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
}

Альтернативное решение, позволяющее определить метод округления:

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
}
1
По вопросам рекламы [email protected]