避免尾随零的printf() [英] Avoid trailing zeroes in printf()

查看:166
本文介绍了避免尾随零的printf()的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直磕磕绊绊的格式说明符的printf()系列的功能。我要的是能够打印双(或浮动)小数点后位数给定的最大数量。如果我使用:

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 after the decimal point. If I use:

printf("%1.3f", 359.01335);
printf("%1.3f", 359.00999);

我得到

359.013
359.010

相反的期望

359.013
359.01

任何人可以帮助我吗?

Can anybody help me?

推荐答案

这不能与正常的的printf 格式说明完成。你可以得到最接近的是:

This can't be done with the normal printf format specifiers. The closest you could get would be:

printf("%.6g", 359.013); // 359.013
printf("%.6g", 359.01);  // 359.01

不过。6是的的数字宽度,

printf("%.6g", 3.01357); // 3.01357

打破它。

什么的能做的就是的sprintf(%。20克)来一个字符串缓冲区的数目,然后操纵字符串只有N个字符过去的小数点。

What you can do is to sprintf("%.20g") the number to a string buffer then manipulate the string to only have N characters past the decimal point.

假设你的号码在变量num,下面的函数将删除所有,但第一个 N 小数,然后剥去尾随零(和小数点,如果他们全0)。

Assuming your number is in the variable num, the following function will remove all but the first N decimals, then strip off the trailing zeros (and decimal point if they were all zeros).

char str[50];
sprintf (str,"%.20g",num);  // Make the number.
morphNumericString (str, 3);
:    :
void morphNumericString (char *s, int n) {
    char *p;
    int count;

    p = strchr (s,'.');         // Find decimal point, if any.
    if (p != NULL) {
        count = n;              // Adjust for more or less decimals.
        while (count >= 0) {    // Maximum decimals allowed.
             count--;
             if (*p == '\0')    // If there's less than desired.
                 break;
             p++;               // Next character.
        }

        *p-- = '\0';            // Truncate string.
        while (*p == '0')       // Remove trailing zeros.
            *p-- = '\0';

        if (*p == '.') {        // If all decimals were zeros, remove ".".
            *p = '\0';
        }
    }
}


如果你不快乐的截断面(这会变成 0.12399 0.123 ,而不是舍入到 0.124 ),你可以实际使用已被的printf 提供的四舍五入设施。你只需要分析号码前手动态创建的宽度,然后使用这些转数成字符串:


If you're not happy with the truncation aspect (which would turn 0.12399 into 0.123 rather than rounding it to 0.124), you can actually use the rounding facilities already provided by printf. You just need to analyse the number before-hand to dynamically create the widths, then use those to turn the number into a string:

#include <stdio.h>

void nDecimals (char *s, double d, int n) {
    int sz; double d2;

    // Allow for negative.

    d2 = (d >= 0) ? d : -d;
    sz = (d >= 0) ? 0 : 1;

    // Add one for each whole digit (0.xx special case).

    if (d2 < 1) sz++;
    while (d2 >= 1) { d2 /= 10.0; sz++; }

    // Adjust for decimal point and fractionals.

    sz += 1 + n;

    // Create format string then use it.

    sprintf (s, "%*.*f", sz, n, d);
}

int main (void) {
    char str[50];
    double num[] = { 40, 359.01335, -359.00999,
        359.01, 3.01357, 0.111111111, 1.1223344 };
    for (int i = 0; i < sizeof(num)/sizeof(*num); i++) {
        nDecimals (str, num[i], 3);
        printf ("%30.20f -> %s\n", num[i], str);
    }
    return 0;
}

nDecimals()在这种情况下,整点是要正确制定出字段宽度,然后格式化使用基于一个格式字符串的数量。测试工具的main()显示这个动作:

The whole point of nDecimals() in this case is to correctly work out the field widths, then format the number using a format string based on that. The test harness main() shows this in action:

  40.00000000000000000000 -> 40.000
 359.01335000000000263753 -> 359.013
-359.00999000000001615263 -> -359.010
 359.00999999999999090505 -> 359.010
   3.01357000000000008200 -> 3.014
   0.11111111099999999852 -> 0.111
   1.12233439999999995429 -> 1.122

一旦你有了正确舍入的值,可以再次传递到 morphNumericString()删除通过简单地改变尾随零:

Once you have the correctly rounded value, you can once again pass that to morphNumericString() to remove trailing zeros by simply changing:

nDecimals (str, num[i], 3);

nDecimals (str, num[i], 3);
morphNumericString (str, 3);

(或调用 morphNumericString 在年底 nDecimals 但是,在这种情况下,我可能只是结合两成一个功能),并且结束了:

(or calling morphNumericString at the end of nDecimals but, in that case, I'd probably just combine the two into one function), and you end up with:

  40.00000000000000000000 -> 40
 359.01335000000000263753 -> 359.013
-359.00999000000001615263 -> -359.01
 359.00999999999999090505 -> 359.01
   3.01357000000000008200 -> 3.014
   0.11111111099999999852 -> 0.111
   1.12233439999999995429 -> 1.122

这篇关于避免尾随零的printf()的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆