6

これに関連する質問がいくつかありますが、この質問に正しく答えるものは見たことがありません。浮動小数点数を出力したいのですが、小数点以下の桁数を適応させたいです。例として:

0      -> 0
1234   -> 1234
0.1234 -> 0.1234
0.3    -> 0.3

厄介なことに、%f指定子は固定された精度でのみ出力されるため、その精度に達しないすべての数値に末尾のゼロが追加されます。一連の数値に対して機能する指定子を提案する人もい%gますが、次のように、一部の数値では科学表記法に切り替わります。

printf("%g", 1000000.0); // prints 1e+06

実際に小数部を持つ数値の printf の標準精度を維持しながら、不必要なゼロなしで浮動小数点数を出力するにはどうすればよいですか?

4

5 に答える 5

11

snprintf一時バッファに印刷してから、末尾の'0'文字を手動で削除するために使用します。正しく、合理的に簡単に実装できる方法は他にありません。

于 2013-03-16T19:25:18.360 に答える
5

問題は、IEEE標準754表現を使用すると、浮動小数点値(小数部を含む)が「後続ゼロ」を持つことができないことです。

x/10^n末尾のゼロは、一部の整数x、nについて小数値を記述できることを意味します。しかし、この標準で表すことができる唯一の分数は、x/2^nいくつかの整数x、nの形式を持っています。

したがって、0.1234と書くものは、バイト0x3D 0xFC0xB90x24を使用して表されます。これは:

Sign = 0
Exponent = 01111011 (which means -4)
Significand: 1.11111001011100100100100

仮数は次のことを意味します:1 + 1/2 + 1/4 + 1/8 + 1/16 + 0/32 + 0/64 + 1/128 + 0/256 + 1/512 + 1/1024 + 1/2048 + 0/4096 + 0/8192+..。

この計算を実行すると、1.974400043487548828125が得られます。

したがって、数は+ 1.974400043487548828125 * 2^(-4)=0.1234000027179718

(もちろん、私はコンピューターを使用してこれを計算したので、同じ理由でオフになる可能性があります...)

ご覧のとおり、コンピューターは、この番号を9桁(0.123400002)ではなく、4桁(のみ)の後に切り刻むことを決定することを望んでいません。重要なのは、コンピューターがこの数値を0.1234として認識せず、後続のゼロの数が無限であるということです。

ですから、Rよりも良い方法はないと思います。

于 2013-03-16T19:44:07.313 に答える
4

試す:

printf("%.20g\n", 1000000.0); // = 1000000

これは、有効数字20桁の後に科学的記数法に切り替わります(デフォルトは「%g」の6桁の後です)。

printf("%.20g\n", 1e+19); // = 10000000000000000000
printf("%.20g\n", 1e+20); // = 1e+20

ただし、倍精度には注意してください。

printf("%.20g\n", 0.12345);   // = 0.12345000000000000417
printf("%.15g\n", 0.12345);   // = 0.12345
于 2013-03-16T19:23:43.903 に答える
0

すでに述べた方法を使用して、これを自分で行うための小さな関数を作成しました。ここでは、テスターを使用しています。バグがないことは保証できませんが、問題ないと思います。

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

char *convert(char *s, double x);

int main()
{
    char str[3][20];
    printf("%s\n%s\n%s\n", convert(str[0], 0),
          convert (str[1], 2823.28920000),
          convert (str[2], 4.000342300));

}

char *convert(char *s, double x)
{
    char *buf = malloc(100);
    char *p;
    int ch;

    sprintf(buf, "%.10f", x);
    p = buf + strlen(buf) - 1;
    while (*p == '0' && *p-- != '.');
    *(p+1) = '\0';
    if (*p == '.') *p = '\0';
    strcpy(s, buf);
    free (buf);
    return s;
}

出力:

0
2823.2892
4.0003423
于 2013-03-16T19:52:50.360 に答える
-1

次のように印刷できます。

printf("%.0f", 1000000.0);

より詳細な回答については、こちらをご覧ください。

于 2013-03-16T19:11:51.820 に答える