不要在C++中输出尾随零
Do Not Output Trailing Zeroes in C++
如果结果是整数,则不输出小数点。
如果结果是浮点数,则不要输出任何尾随零。
如何在c
或c++
中做到这一点:
double result;
/*some operations on result */
printf("%g", result);
上述方法是否正确? 在我的情况下,我没有得到正确的答案。
>您可以使用snprintf
将双精度值打印到char数组中,然后从末尾到头部,将"0"替换为"\0",最后得到一个没有尾随零的数字。这是我的简单代码。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void
remove_zeroes(double number, char * result, int buf_len)
{
char * pos;
int len;
snprintf(result, buf_len, "%lf", number);
len = strlen(result);
pos = result + len - 1;
#if 0
/* according to Jon Cage suggestion, removing this part */
while(*div != '.')
div++;
#endif
while(*pos == '0')
*pos-- = ' ';
if(*pos == '.')
*pos = ' ';
}
int
main(void)
{
double a;
char test[81];
a = 10.1;
printf("before it is %lfn", a);
remove_zeroes(a, test, 81);
printf("after it is %sn", test);
a = 100;
printf("before it is %lfn", a);
remove_zeroes(a, test, 81);
printf("after it is %sn", test);
return 0;
}
输出为
before it is 10.100000
after it is 10.1
before it is 100.000000
after it is 100
我更喜欢可读的代码,这将有效且易于理解。不过,它需要提升。
#include <boost/algorithm/string.hpp>
std::string value = std::to_string((double)12); //yields 12.000000
boost::trim_right_if(value, boost::is_any_of("0")); //turn 12.000000 -> 12.
boost::trim_right_if(value, boost::is_any_of(".")); //turn 12. -> 12
请注意,下面的代码适用于 12,不适用于 120 或 0。您必须将其修剪两个步骤,以免删除小数点左侧的零。所以不要试图保存一行!
std::string value = std::to_string((double)120);
boost::trim_right_if(value, boost::is_any_of("0.")); //yields 12 not 120
评论中有人向我指出,6 位数的精度可能还不够。然后试试这个:
#include <iostream>
#include <sstream>
#include <iomanip>
#include <boost/algorithm/string.hpp>
std::stringstream sStream;
sStream << std::fixed << std::setprecision( 16 ) << (double)12; //yields 12.0000000000000000
std::string value = sStream.str();
boost::trim_right_if(value, boost::is_any_of("0")); //turn 12.000000000000000 -> 12.
boost::trim_right_if(value, boost::is_any_of(".")); //turn 12. -> 12
对于编译器,result
始终是双精度值,因为它是这样声明的。在内部,它具有与整数不同的内存布局。
正确执行要实现的目标,请检查result
是否足够接近自然数,并在打印前将其转换为适当的整数。
如果您知道结果是整数,则可以使用整数变量或简单地转换为整数:
double result;
/*some operations on result */
printf("%d", (int)result);
[编辑] 尝试这样的事情:
#include <stdio.h>
#include <math.h>
void VariablePrecisionPrinter( double num, double precision )
{
if( fabs(num-int(num)) < precision )
{
printf("%dn", (int) num);
}
else
{
printf("%gn", num);
}
}
void Test( )
{
const double Precision = 0.001;
VariablePrecisionPrinter( 100.001, Precision );
VariablePrecisionPrinter( 100.00001, Precision );
VariablePrecisionPrinter( 0.00001, Precision );
VariablePrecisionPrinter( 0.0, Precision );
VariablePrecisionPrinter( 0.1, Precision );
}
。这将打印:
100.001
100
0
0
0.1
[编辑2]
这有点笨拙,但它可以满足您的要求:
#include <string>
#include <stdio.h>
#include <math.h>
using namespace std;
void VariablePrecisionPrinter( double num )
{
// Convert the number to a string
const int tmpSize = 128;
char tmp[tmpSize] = {' '};
sprintf(tmp, "%lf", num);
string truncatedNum = tmp;
// If the conversion ends with a 0, strip the extra parts.
size_t p2 = truncatedNum.find_last_not_of( '0' );
if( string::npos != p2 )
{
truncatedNum = truncatedNum.substr( 0, p2+1 );
// Make sure we're not left with just a decimal point at the end
size_t decimalPos = truncatedNum.find_last_of('.');
if( decimalPos == truncatedNum.length()-1 )
{
truncatedNum = truncatedNum.substr( 0, truncatedNum.length()-1 );
}
}
printf( "%sn", truncatedNum.c_str() );
}
void Test( )
{
const double Precision = 0.001;
VariablePrecisionPrinter( 100.001 );
VariablePrecisionPrinter( 100.00001 );
VariablePrecisionPrinter( 0.00001 );
VariablePrecisionPrinter( 0.0 );
VariablePrecisionPrinter( 0.1 );
}
string DoubleToString (double inValue)
{
std::stringstream buildString;
int i = 0;
double valueWithPrecision = 0;
do
{
buildString.str(std::string());
buildString.clear();
buildString << std::fixed << std::setprecision(i) << inValue;
valueWithPrecision = std::stod(buildString.str().c_str());
i++;
} while (valueWithPrecision != inValue);
return buildString.str();
}
如今,
您应该只为操纵器插入一行:
cout << noshowpoint;
cout << 12.000000000000000 << endl;
或者,在输出之前插入此操作(作为单行),如果它甚至不是默认值。
如果你喜欢相反的方式,那么showpoint
就是你的朋友。
相关文章:
- 递归函数计算序列中的平方和(并输出过程)
- 如何使用 < 和 > 命令获取 c++ 中的输入和输出?
- 请解释"函数1(p1,p2,p3);"的输出
- C++:将控制台输出存储在宏中更好吗
- 创建一个函数以在输入为负数或零时输出字符串.第一次执行用户定义的函数
- 如何在OMNET++中指定与命令行参数组合的输出文件名
- 为什么我的代码在输出中增加了93天
- 如何从void函数输出字符串
- 输入到文件并输出到另一个文件,并将流文件传递给函数
- AES加密到解密未正确输出
- 如何将c++程序的一些输出传递给shell,以便在shell中使用
- 使用C++程序合并排序没有得到正确的输出
- 为什么我不能在不创建字符串变量的情况下使用函数的字符串输出
- C++格式化输出问题
- 将值从二维数组输出到文本文件
- 集合上的输出迭代器:assign和increment迭代器
- 在while循环中输入带有std::cin的字符串后,控制台会输出大量胡言乱语
- 为什么rk4.do_step不输出C++中的初始条件
- 输出没有重复元素的动态数组(收缩数组)C++
- 如何根据单词在文本中出现的概率输出单词