一般に用いられているC言語はC89(別名 ANSI C)と呼ばれる規格で,1989年に制定されたものですが,その後にも新しい機能が取り込まれた以下の規格が制定されています.
上記のうち,C95は数値計算を行う上ではC89とほとんど変わりませんが,C99はC89よりも格段に便利になっており,個人的には今C89の規格で新規に数値計算プログラムを書くのはナンセンスと思います. (しかし,まだ多くの書籍はC89の規格で書かれており,また大学におけるC言語の授業もほとんどはまだC89の規格なので注意が必要です.)
WindowsにおけるC言語処理系で代表的なものは以下です.
上記のうち,1.と2.は基本的にWindowsのアプリケーションをC++で作るためのコンパイラです. そのため,C++は最新の規格に対応しているようですが,CについてはC99の規格を完全に満たしていないようです. また,グラフィックの必要がない数値計算のプログラムを作る場合でも,色々とグラフィックのライブラリとリンクするなど,C以外のところで面倒な手続きがあります.
3.はC/C++ともに最新の規格に対応しており,パソコンでは最速のコンパイラです. しかし,Linux版は商用目的でなければ無料でダウンロードできますが,Windows版は有償のものしかありません.
4.はフリーソフトの世界での標準のコンパイラで様々なOSに移植されており,Unixにおける標準のコンパイラです. また,C/C++ともに最新の規格に対応しています.
WindowsからGCCを使う方法としては,以下の方法があります.
実は,この順番で難易度が上がり,Unixとしての環境もこの順で完全になります. しかし,3, 4は基本的にはUnixに慣れた人が,何らかの理由でWindowsを使わなくてはならないという状況で使うソフトです.
1.のWindows版のGNU Octaveには,MinGWの開発環境とGSL, LAPACKのライブラリが付属しており,Octave-3.6.1およびoctaveforge pkgをインストールしている環境においてコマンドプロンプト内でoctave-gcc-setup.batを実行すればGCCとGSLおよびLAPACKを使うことができます.
以下では 2.の方法について説明しますが,普通のユーザーには Octave をインストールして,コマンドプロンプト内で前述の octave-gcc-setup.bat を実行する1.の方法をお勧めします. なお,以前はコンパイル済みの GSL のバイナリを置いていましたが,更新ができないのでコンパイル方法の説明に変更します.
コンパイラを用意しただけでは数値計算を行うことはできず,以下のような機能を提供するライブラリが必要になります.
この数値計算ライブラリとして有名なのは,以下があります.
1.のIMSLはVisual Numerics社が開発した数値計算用ライブラリで,主に計算機センターなどで使われており,上であげた機能をすべて提供するFortran用のライブラリです. 信頼性には定評がありますがその半面非常に高価です.
2.のLAPACKは,行列計算だけを提供するFortran用のライブラリで,ソースコードがhttp://www.netlib.org/lapack/で公開されています. また,コンピュータメーカやIntelなどでは,使用しているハードウェアに対して最適化したLAPACKを提供しています.
3.のGSLはGNU Scientific Libraryの頭字語(acronym)であり,C言語用にフリーでhttp://www.gnu.org/software/gsl/から公開されているライブラリです. フリーですが,ロスアラモス研究所や各国の大学などの計算科学の専門家が開発に関わっています. また,産総研の富永さんがマニュアルを和訳されhttp://www.cbrc.jp/~tominaga/translations/gsl/で公開しています.
tar zxvf gsl-1.15.tar.gz cd gsl-1.15 ./configure --disable-shared make make install
C:\MinGW\msys\1.0\local\include
内のgsl
フォルダをC:\MinGW\include
にコピーする.
C:\MinGW\msys\1.0\local\lib
内のlibgsl.a, libgslcblas.a
の2つのファイルをC:\MinGW\lib
にコピーする.
インストールされたGSLが正しく動いているかどうか,以下の方法でテストしてみてください.
#include <stdio.h> #include <gsl/gsl_sf_exp.h> int main(void) { printf("e = %20.12e\n", gsl_sf_exp(1.0)); return 0; }
cd "My Documents\gsl"とディレクトリを移動して,以下のコマンドを入力する.
gcc -Wall test_gsl.c -lgsl -lgslcblas最初の
-Wall
は,コンパイラが警告をすべて出力すると言う意味で,gccを使うときはいつも指定すると良い.
後ろ2つの-lgsl
, -lgslcblas
はGSLのライブラリを実行プログラムにリンクする指定です.
作成したプログラムに誤りがなければ,何も出力がなくプロンプトが返ってくるので,
aと実行する. なお,gccでの実行ファイルは,コンパイル時に"-o"オプションで指定しない限り,いつでもa.exeである. プログラムが問題なく作成されていれば,
e = 2.718281828459e+000のように出力されるはずです..
Linuxで動く数値計算プログラムをMinGWに移植する際には,以下に注意しなければなりません.
このために,LinuxとWindowsで以下の相違があります.
そのため,Linuxにおいて浮動小数点を表示するとき間に空白を1つだけあけるようにしていた場合にMinGWでは空白がなくなってしまいます.
こちらについては現在のところということで,将来はどうなるか分かりません.
このために,MinGWでは別ページで紹介しているGNU/LinuxにおけるInfやNaNの発生場所を特定する方法とtrapfpe.cのプログラムが異なってきます.
具体的には,Windows + MinGWにおいてInfやNaNの発生場所を特定する方法は以下の手順となります.
trapfpe-windows.c
を記述する.
#include <float.h> static void __attribute__ ((constructor)) trapfpe () { _controlfp( ~(_EM_INVALID|_EM_ZERODIVIDE|_EM_OVERFLOW), _MCW_EM ); }
trapfpe-windows.c
を以下のようにコンパイルして,libtrapfpe.a
を作成する.
(前述の octave-gcc-setup.bat で Octave の開発環境を利用する場合は,"C:\MinGW\include" の代わりに,"%octave_path%\mingw32\include" としてください.)
> gcc -c -isystem C:\MinGW\include trapfpe.c -o libtrapfpe.a
libtrapfpe.a
をC:\MinGW\lib
にコピーする.
(前述の octave-gcc-setup.bat で Octave の開発環境を利用する場合は,Octaveのインストール・ディレクトリの下の "mingw32\lib" にコピーしてください.)
> gcc -Wall -g hoge.c -ltrapfpe
> gdb a.exe
なお,gdbはデバッガなので,変数の値を表示する("print 変数名")などデバッグに便利な機能をたくさん備えています. gdbの機能についてさらに詳しく知りたい人は,マニュアルなどを調べて下さい.
また,gdbを終了させるコマンドは"quit"です. "quit"を入力すると,
The program is running. Exit anyway? (y or n)
というメッセージが出力されて応答待ちとなるので,"y"を入力してgdbを終了させてください.
このため,大きな配列を宣言している場合には,実行時に以下のウィンドウによるエラーメッセージが出ることがあります.
このような場合にはコンパイル時に以下のようにしてスタックサイズを指定する必要があります.
gcc -Wl,--stack,10485760 hoge.c
上記は10485760Byte=10MBの指定です. 1つの変数が占めるメモリは,倍精度実数が8バイト,倍精度複素数が16バイト,整数が4バイトであることより必要なスタック領域を見積もり,余裕を持った値を指定して下さい. なお,kやmなどの修飾子は指定できません.
こんなオプションを毎回指定するのは大変なので,次に自動化の手段を考えます. バッチファイルなどの手段もありますが,標準的にはmakeを使います. 筆者が別ページに書いた記述を参考にこの場合のmakefileを書くとこのようになります. なお,MinGWにおけるmakefileはLinuxにおけるmakefileと以下が異なるので注意する必要があります.
また,上記のようなmakefileを使う場合には,ソースファイル(複数のファイルがある場合には,どれか1つ)の拡張子を.exeに変更したものを実行ファイル名としなければなりません.
Last update: 2012.3.19