【问题标题】:Show some decimal places C显示一些小数位 C
【发布时间】:2014-11-22 23:52:36
【问题描述】:

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

我的程序要求一定数量的位并将其转换为 mb、kb 和字节。所以,如果我输入 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 位小数,我只是在尝试哪种方式是我输出值的最佳方式。

提前谢谢你!

【问题讨论】:

标签: c printf


【解决方案1】:

使用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 不是整数。

【讨论】:

  • 欢迎您@IgnasiSánchez。你也提出了一个很好的问题,因此我的+1。 :)
【解决方案2】:

您可以创建一个函数来计算所需的小数位数。为此,请取小数部分,然后将其乘以 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,因为我不确定在long double 上调用库函数floor 是否正确。我还在格式字符串中将Lf 更改为flong double(如果有的话)的额外精度在您在这里进行的计算中是不需要的。

【讨论】:

  • 这个很灵,也是我最后用的那个。非常感谢!
【解决方案3】:

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

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)) &lt; 1.0e-5*abs(x))

顺便说一句,请注意bignum-s,如果您需要大量(超过 8 个)小数,请考虑使用 GMPlib

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-09-13
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多