windows, gcc, long double, prinf
Cでlong doubleをフォーマット出力しようとしたら失敗したので備忘録。
調べてみると解決策っぽいのが見つかったが日本語情報はなかったのでメモしておく。
stackoverflowにあった。
問題
環境はWindows10、MinGW64のターミナルからgccで、long doubleが16バイトの環境になってる。
コードはこんな感じ。
#include <stdio.h> int main() { long double ld = 0.1L; printf("sizeof(long double): %d\n", sizeof(long double)); printf("sizeof(double): %d\n", sizeof(double)); printf("ld = %Le\n", ld); return 0; }
コンパイルして実行
$ gcc test.c $ ./a.exe sizeof(long double): 16 sizeof(double): 8 ld = 3.205300e-317
MinGWだと内部でWindowsのruntimeで出力しようとしているのが原因っぽい。
Windowsだとsizeof(long double) == 8
だけど、MinGWのgccだとsizeof(long double) == 16
だから不整合が起きる。
解決策
解決策は-D__USE_MINGW_ANSI_STDIO
のオプションをコンパイル時に指定すればいい。
こんな感じになる。
$ gcc test.c -D__USE_MINGW_ANSI_STDIO $ ./a.exe sizeof(long double): 16 sizeof(double): 8 ld = 1.000000e-001
こうすればANSI規格かなんかになっているstdioを優先して使ってくれるような感じで上手くいくっぽい。 詳しく調べてないから具体的には分からない。
long double自体ビット長が環境によって結構違うっぽい(80bitとかもあるみたい)なので、使うのはできるだけ避けるかsizeof
でビット長が想定している長さかをチェックした方がいい。
gccなら拡張機能として128bitの浮動小数点があるのでそっちが使えるかもしれない。