Avoid trailing zeroes in printf()

前端 未结 14 2426
猫巷女王i
猫巷女王i 2020-11-22 07:18

I keep stumbling on the format specifiers for the printf() family of functions. What I want is to be able to print a double (or float) with a maximum given number of digits

14条回答
  •  佛祖请我去吃肉
    2020-11-22 07:45

    A simple solution but it gets the job done, assigns a known length and precision and avoids the chance of going exponential format (which is a risk when you use %g):

    // Since we are only interested in 3 decimal places, this function
    // can avoid any potential miniscule floating point differences
    // which can return false when using "=="
    int DoubleEquals(double i, double j)
    {
        return (fabs(i - j) < 0.000001);
    }
    
    void PrintMaxThreeDecimal(double d)
    {
        if (DoubleEquals(d, floor(d)))
            printf("%.0f", d);
        else if (DoubleEquals(d * 10, floor(d * 10)))
            printf("%.1f", d);
        else if (DoubleEquals(d * 100, floor(d* 100)))
            printf("%.2f", d);
        else
            printf("%.3f", d);
    }
    

    Add or remove "elses" if you want a max of 2 decimals; 4 decimals; etc.

    For example if you wanted 2 decimals:

    void PrintMaxTwoDecimal(double d)
    {
        if (DoubleEquals(d, floor(d)))
            printf("%.0f", d);
        else if (DoubleEquals(d * 10, floor(d * 10)))
            printf("%.1f", d);
        else
            printf("%.2f", d);
    }
    

    If you want to specify the minimum width to keep fields aligned, increment as necessary, for example:

    void PrintAlignedMaxThreeDecimal(double d)
    {
        if (DoubleEquals(d, floor(d)))
            printf("%7.0f", d);
        else if (DoubleEquals(d * 10, floor(d * 10)))
            printf("%9.1f", d);
        else if (DoubleEquals(d * 100, floor(d* 100)))
            printf("%10.2f", d);
        else
            printf("%11.3f", d);
    }
    

    You could also convert that to a function where you pass the desired width of the field:

    void PrintAlignedWidthMaxThreeDecimal(int w, double d)
    {
        if (DoubleEquals(d, floor(d)))
            printf("%*.0f", w-4, d);
        else if (DoubleEquals(d * 10, floor(d * 10)))
            printf("%*.1f", w-2, d);
        else if (DoubleEquals(d * 100, floor(d* 100)))
            printf("%*.2f", w-1, d);
        else
            printf("%*.3f", w, d);
    }
    

提交回复
热议问题