Do not output trailing zeros in C ++

If the result is an integer, do not print the decimal point.

If the result is a floating point number, do not output any trailing zeros.

How to do it in c or c++ :

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

Is this approach correct? I do not get the right answer in my situation.

+3
c ++ c
source share
6 answers

you can use snprintf to print a double value into a char array, then from end to head, replace '0' with '\ 0', finally you will get a number without zero zeros. Here is my simple code.

 #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-- = '\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; } 

and the way out is

 before it is 10.100000 after it is 10.1 before it is 100.000000 after it is 100 
+4
source share

I prefer readable code and this will work and will be easy to understand. It requires a boost though.

 #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 

Please note that the code below will work for 12, it will not work for 120 or 0. You must trim it in two steps so as not to remove zeros at the left end of the decimal point. So do not try to save the line!

 std::string value = std::to_string((double)120); boost::trim_right_if(value, boost::is_any_of("0.")); //yields 12 not 120 

The comments indicated that six-digit accuracy may not be enough. Then try the following:

 #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 
+1
source share

If you know that the result is an integer, you can either use an integer variable, or simply pass an integer:

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

[Edit] Try something like this:

 #include <stdio.h> #include <math.h> 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 ); } 

... which will print:

 100.001 100 0 0 0.1 

[Edit2]

This is a bit awkward, but it does what you ask for:

 #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] = {'\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 ); } 
0
source share

For the compiler, result always double, because it is declared as such. Inside, it has a different memory structure than an integer.

Correctly do what you want to check if result is close enough to the natural number and apply it to the corresponding integer before printing.

0
source share
 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(); } 
0
source share

For now, you should just insert one line for the manipulator:

 cout << noshowpoint; cout << 12.000000000000000 << endl; 

Alternatively, insert this manipulation just before the output (like oneliner), if it is not even used by default.

If you like the other way around, then showpoint your friend.

0
source share

All Articles