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 ...
間違った修飾子に加えて、Windowsへのgccのポートはどれですか? mingwはMicrosoft Cライブラリを使用しますが、このライブラリは80ビット長倍精度をサポートしていないことを覚えているようです(Microsoft Cコンパイラはさまざまな理由で64ビット長倍精度を使用します)。
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など)とランタイムが混同していないように見える..
はい-long double
の場合、%Lf
(つまり、大文字の 'L')を使用する必要があります。
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バージョンを有効にする)を使用することもできます。
ロングダブルをテストするこの問題を抱えていましたが、悲しいかな、私は修正に出会いました! -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;
}
C99では、long double
の長さ修飾子はL
ではなくl
であるようです。 man fprintf
(またはWindowsの同等のもの)は、特定のプラットフォームを示しています。
他の回答で述べたように、正しい変換指定子は"%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` $
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