web-dev-qa-db-ja.com

printfとlong double

Windows上のNetbeansで最新のgccを使用しています。 long doubleが機能しないのはなぜですか? printf指定子%lfは間違っていますか?

コード:

#include <stdio.h>

int main(void)
{
    float aboat = 32000.0;
    double abet = 5.32e-5;
    long double dip = 5.32e-5;

    printf("%f can be written %e\n", aboat, aboat);
    printf("%f can be written %e\n", abet, abet);
    printf("%lf can be written %le\n", dip, dip);

    return 0;
}

出力:

32000.000000 can be written 3.200000e+004
0.000053 can be written 5.320000e-005
-1950228512509697500000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000000000000000.000000
can be written 2.725000e+002
Press [Enter] to close the terminal ...
52
gameboy

間違った修飾子に加えて、Windowsへのgccのポートはどれですか? mingwはMicrosoft Cライブラリを使用しますが、このライブラリは80ビット長倍精度をサポートしていないことを覚えているようです(Microsoft Cコンパイラはさまざまな理由で64ビット長倍精度を使用します)。

14
AProgrammer

Printfのマンページから:

l(エル)次の整数変換はlong intまたはunsigned long int引数に対応します。または、後続のn変換はlong int引数へのポインターに対応します。または、後続のc変換はwint_t引数に対応します。 wchar_t引数へのポインターに対応します。

そして

A、A、e、E、f、F、g、またはG変換に続くL Aは、long double引数に対応します。 (C99は%LFを許可しますが、SUSv2は許可しません。)

したがって、%Leではなく%leが必要です。

編集:いくつかのさらなる調査は、MingwがMSVC/win32ランタイム(printfなど)を使用していることを示しているようです-long doubleをdoubleにマップします。そのため、ネイティブのlong doubleを提供するコンパイラ(gccなど)とランタイムが混同していないように見える..

42
nos

はい-long doubleの場合、%Lf(つまり、大文字の 'L')を使用する必要があります。

37
Jerry Coffin

MinGWを使用している場合、問題はデフォルトでMinGWがI/O応答を使用することです。 80ビット浮動小数点数をサポートしないMicrosoft Cランタイムからのフォーマット関数(Microsoftのlong double == double)。

ただし、MinGWには、do long doubleを適切にサポートする代替実装のセットも付属しています。それらを使用するには、関数名の前に__mingw_を付けます(例:__mingw_printf)。プロジェクトの性質に応じて、#define printf __mingw_printfをグローバルに使用するか、-D__USE_MINGW_ANSI_STDIO(すべてのprintf- family関数のMinGWバージョンを有効にする)を使用することもできます。

23
klickverbot

ロングダブルをテストするこの問題を抱えていましたが、悲しいかな、私は修正に出会いました! -D__USE_MINGW_ANSI_STDIOを使用してプロジェクトをコンパイルする必要があります。

Jason Huntley @ centurian /home/developer/dependencies/Python-2.7.3/test $ gcc main.c

Jason Huntley @ centurian /home/developer/dependencies/Python-2.7.3/test $ a.exe c = 0.000000

Jason Huntley @ centurian /home/developer/dependencies/Python-2.7.3/test $ gcc main.c -D__USE_MINGW_ANSI_STDIO

Jason Huntley @ centurian /home/developer/dependencies/Python-2.7.3/test $ a.exe c = 42.000000

コード:

Jason Huntley@centurian /home/developer/dependencies/Python-2.7.3/test
$ cat main.c
#include <stdio.h>

int main(int argc, char **argv)
{
   long double c=42;

   c/3;

   printf("c=%Lf\n",c);

   return 0;
}
6
Jason Huntley

C99では、long doubleの長さ修飾子はLではなくlであるようです。 man fprintf(またはWindowsの同等のもの)は、特定のプラットフォームを示しています。

4
Jens Gustedt

他の回答で述べたように、正しい変換指定子は"%Lf"です。

Gcc呼び出しで-Wformat(または-Wallを含む-Wformat)を使用して、フォーマットの警告をオンにすることができます。

 $ gcc source.c 
 $ gcc -Wall source.c 
 source.c:関数 `main`:
 source.c:5:警告:形式 "%lf"は型 `double`を想定していますが、引数2は型` long double` 
 source.c:5:警告:形式 "%le"は型 `double`を想定していますが、引数3は型` long double` 
 $ 
2
pmg

c/C++のprintfおよびscanf関数はMicrosoft Cライブラリを使用し、このライブラリは10バイト長のdoubleをサポートしていません。したがって、C/C++コードでprintfおよびscanf関数を使用してlong doubleを出力として出力し、一部の入力をlong doubleとして使用すると、常に間違った結果が得られます。

Long doubleを使用する場合は、printfとscanfの代わりに「__mingw_printf」および「__mingw_scanf」関数を使用する必要があります。 10バイト長のdoubleをサポートしています。

または、「#define printf __mingw_printf」と「#define scanf __mingw_scanf」のような2つのマクロを定義できます。

Long doubleの標準形式を使用:%Lf

0
Rupak Paul