不要在C ++中输出尾随零

如果结果是整数, 则不输出小数点。

如果结果是浮点数, 请不要输出任何尾随零。

如何在cc++做到这一点:

 double result; /*some operations on result */ printf("%g", result); 

上述方法是否正确? 在我的情况下,我没有得到正确答案。

你可以使用snprintf将double值打印到一个char数组中,然后从头到头,用’\ 0’替换’0’,最后得到一个没有填充零的数字。这是我的简单代码。

 #include  #include  #include  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-- = '\0'; if(*pos == '.') *pos = '\0'; } int main(void) { double a; char test[81]; a = 10.1; printf("before it is %lf\n", a); remove_zeroes(a, test, 81); printf("after it is %s\n", test); a = 100; printf("before it is %lf\n", a); remove_zeroes(a, test, 81); printf("after it is %s\n", test); return 0; } 

而输出是

 before it is 10.100000 after it is 10.1 before it is 100.000000 after it is 100 

我更喜欢可读的代码,这将工作并易于理解。 但它需要提升。

 #include  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  #include  #include  #include  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总是一个double,因为它是这样声明的。 在内部,它具有与整数不同的内存布局。

要正确执行您想要实现的目标,请检查result是否足够接近自然数并在打印前将其转换为适当的整数。

如果您知道结果是整数,则可以使用整数变量或简单地转换为整数:

 double result; /*some operations on result */ printf("%d", (int)result); 

[编辑]尝试这样的事情:

 #include  #include  void VariablePrecisionPrinter( double num, double precision ) { if( fabs(num-int(num)) < precision ) { printf("%d\n", (int) num); } else { printf("%g\n", 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 

[EDIT2]

这有点笨拙,但它符合你的要求:

 #include  #include  #include  using namespace std; void VariablePrecisionPrinter( double num ) { // Convert the number to a string const int tmpSize = 128; char tmp[tmpSize] = {'\0'}; 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( "%s\n", 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(); }