显示一些小数位C.

时间:2014-09-28 13:42:11

标签: c printf

我正在为课程编写一个简单的程序。我已经完成了,不用担心,我不是要求任何人做我的功课。让我用一个例子来解释我想要的东西。

我的程序要求一定数量的位并将其转换为mb,kb和bytes。因此,输入1位时的输出是:

1 in megabytes is: 0.000000119209290
1 in kilobytes is: 0.000122070312500
1 in bytes is: 0.125000000000000
1 in bits is: 1

所以,我的问题只是一个美学问题:我怎么能不显示不必要的小数位?例如,在字节中,我只想打印0.125 而不是15位小数,这根本不是那么漂亮。

源代码是:

#include <stdio.h>
#include <stdlib.h>
#include <math.h>

int main(void)
{

        unsigned long long int bits;

        printf("Input a quantity of bits: \n");
        scanf("%lld", &bits);

    /*
     * 1 byte = 8 bits.
     * 1 kilobyte = 1024 bytes.
     * 1 megabyte = 1024 kilobytes.
     */
        long double by = ((double) bits) / ((double) 8);
        long double kb = ((double) by)  / ((double) 1024);
        long double mb = ((double) kb) / ((double) 1024);

        printf("%lld in megabytes is: %.15Lf\n", bits, mb);
        printf("%lld in kilobytes is: %.15Lf\n", bits, kb);
        printf("%lld in bytes is: %.15Lf\n", bits, by);
        printf("%lld in bits is: %lld\n", bits, bits);

    return(0);
}

PS:我知道我在printf中指定了15个小数位,我只是尝试这是输出值的最佳方法。

提前谢谢!

3 个答案:

答案 0 :(得分:4)

使用g说明符,如下所示:

printf("%lld in megabytes is: %.15Lg\n", bits, mb);
printf("%lld in kilobytes is: %.15Lg\n", bits, kb);
printf("%lld in bytes is: %.15Lg\n", bits, by);
printf("%lld in bits is: %lld\n", bits, bits);

但是,如果需要,这将使用科学记数法。你可以像这样添加一个if语句:

if(fmod(mb, 10) == mb // last digit is not zero
    && mb < 0.000001) // if mb is a small number (the left value may need tuning)
   printf("%lld in megabytes is: %.15Lf\n", bits, mb);
else
   printf("%lld in megabytes is: %.15Lg\n", bits, mb);

相关答案是this。还要注意,我必须使用fmod()(在math.h下),因为mb 不是一个整数。

答案 1 :(得分:1)

您可以创建一个函数来计算所需的小数位数。为此,取小数部分,然后乘以10,直到它变为整数。

int required_decimal_places(double x)
{
    int counter = 0;

    x -= floor(x);
    while (x != floor(x))
    {
        x *= 10;
        ++counter;
    }

    return counter;
}

然后,输出您所需的小数位数:

printf("%lld in megabytes is: %.*f\n", bits, required_decimal_places(mb), mb);

格式字符串中的星号(*)告诉系统输出的长度被指定为参数。

注意:我在代码中用long double替换了double,因为我不确定在floor上调用库函数long double是否正确。我还在格式字符串中将Lf更改为f。在此处进行的计算中不需要long double(如果有)的额外准确度。

答案 2 :(得分:0)

可能的方法是打印成字符串,然后检查字符串是否足够准确:

double x= some_number();
char buf[48];
snprintf (buf, sizeof(buf), "%.3f", x);
if (atof(buf) == x) puts(buf);
else {
  snprintf (buf, sizeof(buf), "%.6f", x);
  if (atof(buf) == x) puts(buf);
  else printf("%.15g", x);
}

阅读floating point guide;考虑与某些epsilon进行比较,例如if (abs(x-atof(buf)) < 1.0e-5*abs(x))

BTW,请注意bignum - s并考虑GMPlib是否需要很多(超过8个)小数。