简体   繁体   English

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

[英]Do Not Output Trailing Zeroes in C++

If the result is an integer, do not output the decimal point. 如果结果是整数, 则不输出小数点。

If the result is a floating point number, do not output any trailing zeroes. 如果结果是浮点数, 请不要输出任何尾随零。

How to do it in c or c++ : 如何在cc++做到这一点:

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

Is the above approach correct? 上述方法是否正确? I'm not getting the correct answer with in my situation. 在我的情况下,我没有得到正确答案。

you can use snprintf to print the double value into a char array, then from the end to the head, replace the '0' with '\\0', finally you get a the number without tailling zeroes.Here is my simple code. 你可以使用snprintf将double值打印到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-- = '\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 output is 而输出是

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

I prefer readable code and this will work and be easy to understand. 我更喜欢可读的代码,这将是有效的,易于理解。 It requires 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

Note that the code below will work for 12 it will not work for 120 or 0. You must trim it two steps to not remove zeros to the immediate left of the decimal point. 请注意,下面的代码将适用于12,它将不适用于120或0.您必须修剪它两步,不要删除小数点左边的零。 So don't try to save a line! 所以不要试图保存一条线!

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

It was pointed out to me in the comments that 6 digit precision might not be enough. 在评论中我指出,6位精度可能还不够。 Then try this: 然后尝试这个:

#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

If you know the result is an integer, you could either use an integer variable or simply cast to 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] [EDIT2]

This is a bit clunky but it does what you ask: 这有点笨拙,但它会按你的要求做:

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

For the compiler result is always a double because it's declared as such. 对于编译器result总是一个double,因为它是这样声明的。 Internally it has a different memory layout than an integer. 在内部,它具有与整数不同的内存布局。

To do properly what you want to achieve check if result is close enough to a natural number and cast it to an appropriate integer before printing. 要正确执行您想要实现的目标,请检查result是否足够接近自然数并在打印前将其转换为适当的整数。

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

Nowadays you should just insert one line for the manipulator: 现在你应该为操纵器插入一行:

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

Alternatively insert this manipulation just before your output (as oneliner) if its not even the default. 或者,如果它不是默认值,则在输出之前插入此操作(如oneliner)。

If you like the other way around, then showpoint is your friend. 如果您喜欢相反的方式,那么showpoint就是您的朋友。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM