我可以把-0.000打印成0.000吗?
Can I print -0.000 as 0.000?
printf("%.3lfn", -0.0001);
输出-0.000
,但不应该是0.000
吗?
我如何使这个打印没有负号,即0.000
?
c++从C继承了printf
。在C11标准§7.21.6.1 fprintf
函数中,脚注说:
所有对负零的浮点转换的结果,以及对四舍五入为零的负值的浮点转换的结果,包含一个负号
正确答案已经给出了。只是想补充一下,您将从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("%.3lfn", 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
所以它似乎工作!
但它并不适用于所有四舍五入模式。
因此,使用第一个版本的string convert似乎更安全。
浮点表示(https://en.wikipedia.org/wiki/Floating_point)有一个符号位。实现printf的人决定显式地把它放在那里,即使所有打印的数字都是0。
编辑:我以前的解决方案没有解决问题,因为它应该。
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: %.3lfn", -0.0001);
printf("round : %.3lfn", round<3>(-0.0001));
system("PAUSE");
}
结果:printf: -0.000整数:0.000
比较printf w/precision和round
int main()
{
printf("printf: %05.2lfn", 12345.6789);
printf("printf: %05.2lfn", 12345.1234);
printf("n");
printf("round : %05.2lfn", round<2, std::round>(12345.6789));
printf("round : %05.2lfn", round<2, std::round>(12345.1234));
printf("n");
printf("floor : %05.2lfn", round<2, std::floor>(12345.6789));
printf("floor : %05.2lfn", round<2, std::floor>(12345.1234));
printf("n");
printf("ceil : %05.2lfn", round<2, std::ceil>(12345.6789));
printf("ceil : %05.2lfn", 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.4lfn", round<4>(12345.6789)); //Output = 12345.6789
printf("%5.4lfn", round<3>(12345.6789)); //Output = 12345.6790
printf("%5.4lfn", round<2>(12345.6789)); //Output = 12345.6800
printf("%5.4lfn", round<1>(12345.6789)); //Output = 12345.7000
printf("%5.4lfn", round<0>(12345.6789)); //Output = 12346.0000
printf("%5.4lfn", round<-1>(12345.6789)); //Output = 12350.0000
printf("%5.4lfn", round<-2>(12345.6789)); //Output = 12300.0000
printf("%5.4lfn", round<-3>(12345.6789)); //Output = 12000.0000
printf("%5.4lfn", round<-4>(12345.6789)); //Output = 10000.0000
printf("%5.4lfn", round<-5>(12345.6789)); //Output = 0.0000
//Cut off/Round down after precision
printf("%5.4lfn", round_down<4>(12345.6789)); //Output = 12345.6789
printf("%5.4lfn", round_down<3>(12345.6789)); //Output = 12345.6780
printf("%5.4lfn", round_down<2>(12345.6789)); //Output = 12345.6700
printf("%5.4lfn", round_down<1>(12345.6789)); //Output = 12345.6000
printf("%5.4lfn", round_down<0>(12345.6789)); //Output = 12345.0000
printf("%5.4lfn", round_down<-1>(12345.6789)); //Output = 12340.0000
printf("%5.4lfn", round_down<-2>(12345.6789)); //Output = 12300.0000
printf("%5.4lfn", round_down<-3>(12345.6789)); //Output = 12000.0000
printf("%5.4lfn", round_down<-4>(12345.6789)); //Output = 10000.0000
printf("%5.4lfn", 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.4lfn", round(12345.6789)); //Output = 12345.0000
printf("%05.4lfn", round<1>(12345.6789)); //Output = 12345.7000
printf("%05.4lfn", round<1, std::round>(12345.6789)); //Output = 12345.7000
printf("%05.4lfn", round<1, std::floor>(12345.6789)); //Output = 12345.6000
printf("%05.4lfn", round<1, std::ceil>(12345.6789)); //Output = 12345.7000
}
相关文章:
- 函数向量_指针有不同的原型,我可以构建一个吗
- 我可以使用 g++ 进行三种比较 (<=>) 吗?
- 这个指针和内存代码打印是什么?我不知道是打印垃圾还是如何打印我需要的值
- 我可以使用条件运算符初始化C风格的字符串文字吗
- 我可以避免通过time_t打印时间点吗
- 为什么我可以通过SubBase类的公共继承方法打印出基类的私人继承成员
- 了解文件输入和输出,我可以写入文件,但无法从文件打印
- 无论如何,我可以从WAV文件中打印Sox即可打印幅度值
- 我可以在 Xcode 的消息/警告中打印出预处理器值吗?
- 我可以使用我打印到控制台窗口的内容作为输入吗
- 为什么我可以打印动态分配的对象,但不能打印使用 cout <<在堆栈上创建的对象
- 我可以使用 printf() 打印类的对象吗?
- 我可以用cout而不是迭代器循环打印STL映射吗?
- 在c++中的字符串类数组中不打印任何内容,即使我可以访问单个元素
- 我不能打印我的书的名字,但可以打印其他所有的东西
- 用程序打印时,我可以为每页指定不同的页面大小吗
- typedef int -> 整数。我可以在 c++ 中执行 cout-> 打印吗?
- 为什么我可以打印空列表中的第一个元素
- 我可以把-0.000打印成0.000吗?
- 我可以使用什么Mac/iOS/便携式库来格式化信息以打印到标签纸上