
C言語で数学関数を使う機会はまずない。
だが、基本的な関数の使い方を理解しておくと、いざというときに役立つかもしれない。
強力な数学関数群を活用できれば、複雑な計算もスムーズに行える。この記事では、C言語でよく使われる数学関数の使い方を解説していく。
C言語で数学関数を扱う準備と基本知識
C言語で高度な数学計算を行うには、まず必要な準備をしておく必要がある。標準の数値演算では整数や単純な四則演算しか扱えないが、三角関数や平方根などを使うときは、標準ライブラリの一つである math.h を使う。このヘッダーファイルには、よく使われる数学関数が多数用意されており、C言語のソースコードの冒頭に #include と書くだけで使えるようになる。
ただし、math.h の関数を使うには、プログラムをコンパイルするときに追加のオプションが必要になることがある。たとえば、GCCを使う場合は、次のように -lm を付けて数学ライブラリをリンクする。
gcc program.c -o program -lmGeanyでのビルドコマンド
表示されるダイアログの「コンパイル」欄を
gcc -Wall -c "%f"「ビルド」欄に
gcc -Wall "%f" -o "%e" -lmこの「-lm」は「math library(数学ライブラリ)」を意味しており、これを忘れるとリンクエラーになることがあるので注意したい。
こうした準備をしておけば、C言語で sin() や sqrt() などの関数を自由に使えるようになる。
数値計算を正しく行うためには、データ型にも注意が必要だ。これらの関数は通常、double 型の引数と戻り値を扱う。整数をそのまま渡すと正確な結果が得られないことがあるので、必要に応じて double 型に変換してから使うようにしたい。
切り上げ・切り下げ・絶対値などの基本数学関数
C言語では、小数の処理や符号付き数値の扱いに便利な関数がいくつか用意されている。中でもよく使われるのが、floor()、ceil()、fabs() の3つだ。これらはすべて math.h に含まれており、double 型の数値を引数として受け取る。
floor()
floor() は与えられた小数を超えない最大の整数に切り下げる関数だ。floor() の語源は、英単語の “floor”(床) に由来する。英語の “floor” には、「下限を切り下げる」という数学的な意味がある。
たとえば floor(3.7) は 3.0 を返し、floor(-2.1) は -3.0 を返す。負の数の場合は絶対値が大きくなる方向に切り下げられる点に注意が必要だ。
#include <stdio.h>
#include <math.h>
int main() {
double num1 = 3.7;
double num2 = -2.3;
printf("floor(%.2f) = %.2f\n", num1, floor(num1)); // 3.00
printf("floor(%.2f) = %.2f\n", num2, floor(num2)); // -3.00
return 0;
}出力
floor(3.70) = 3.00 // 3.7 → 3.00
floor(-2.30) = -3.00 // -2.3 → 3.00ceil()
一方、ceil() は小数を超える最小の整数に切り上げる。ceil() の語源は、英単語 “ceiling”(天井) に由来し、上限を意味する。つまり ceil(3.2) は 4.0 を、ceil(-2.8) は -2.0 を返す。こちらも負の数を扱うときに誤解しやすいため、動作を確認しながら使ったほうがいい。
#include <stdio.h>
#include <math.h>
int main() {
double num1 = 3.7;
double num2 = -2.3;
printf("ceil(%.2f) = %.2f\n", num1, ceil(num1)); // 4.00
printf("ceil(%.2f) = %.2f\n", num2, ceil(num2)); // -2.00
return 0;
}出力
ceil(3.70) = 4.00 // 3.7 → 4.00
ceil(-2.30) = -2.00 // -2.3 → -2.00fabs()
絶対値を求めたいときは fabs() を使う。これは「floating absolute」の略で、引数の符号を取り除いた値を返す。たとえば fabs(-5.25) は 5.25、fabs(3.0) はそのまま 3.0 となる。整数値ではなく、浮動小数点の絶対値を扱うことに特化している点がポイントだ。
#include <stdio.h>
#include <math.h>
int main() {
double num1 = 3.7;
double num2 = -2.3;
printf("fabs(%.2f) = %.2f\n", num1, fabs(num1)); // 3.70
printf("fabs(%.2f) = %.2f\n", num2, fabs(num2)); // 2.30
return 0;
}出力
fabs(3.70) = 3.70 // 3.7 → 3.70
fabs(-2.30) = 2.30 // -2.3 → 2.30これらの関数は、四捨五入とは異なる動作をするため、処理の意図に合わせて使い分けることが大切だ。
表示用に整数にしたいだけなら、printf(“%.0f”, 値) のようにフォーマット指定で丸める方法があるが、これは表示上の話であり、実際の値は変わらない点に注意しておきたい。
べき乗と平方根の計算方法とエラー回避
C言語で累乗や平方根を求めたいときは、pow() と sqrt() を使うのが基本だ。どちらも math.h に定義されていて、引数として double 型の値を受け取る。たとえば「4の6乗」は pow(4, 6) と書く。戻り値も double になるため、結果を整数として使いたいときは型変換を忘れないようにしたい。
pow()
pow は power の短縮形。数学で x^y を「x の y 乗」と言い、「x raised to the power of y」と表現することから来ている。
#include <stdio.h>
#include <math.h>
int main() {
double base = 4.0;
double exponent = 6.0;
double result = pow(base, exponent);
printf("%.2f の %.2f 乗は %.2f です。\n", base, exponent, result);
return 0;
}sqrt()
sqrt() は平方根を計算する関数で、sqrt(16.0) は 4.0 を返す。
sqrt は square root の略(square = 二乗, root = 根)。「平方根」=「2乗して元に戻る数」のこと。
引数が負の数だと実行時に不正な動作になる可能性がある。C言語には虚数(複素数)の概念が標準ではないため、負の平方根は扱えない。たとえば sqrt(-9.0) を実行すると未定義動作になり、エラーや異常な数値を返すことがある。
#include <stdio.h>
#include <math.h>
int main() {
double value = 16.0;
double result = sqrt(value);
printf("%.2f の平方根は %.2f です。\n", value, result);
return 0;
}fabs()
こうした問題を避けるには、事前に値が負かどうかを確認するのが安全だ。そのときに便利なのが fabs() だ。
fabs() の語源は、”floating-point absolute”(浮動小数点の絶対値) の略。この関数で負の数をあらかじめ正に変換してから sqrt() に渡せば、確実に計算ができる。たとえば次のように使える。
double x = sqrt(fabs(value));#include <stdio.h>
#include <math.h>
int main() {
double value = -25.0;
// fabs()で絶対値に変換してから平方根を計算
double result = sqrt(fabs(value));
printf("値 %.2f の絶対値の平方根は %.2f です。\n", value, result);
return 0;
}値 -25.00 の絶対値の平方根は 5.00 です。// -25.0 → 25.0 → 5.0本来は負の数の平方根が意味を持たないケースでは、このように無理に計算せず、ロジック全体を見直すほうが望ましいこともある。プログラムの目的に応じて、安全かつ正確な計算処理を設計することが大切だ。誤った数値をそのまま使うと、後続の処理にも影響を及ぼすため注意したい。
三角関数の使い方とラジアン変換の実践
C言語で三角関数を使うには、sin()、cos()、tan() などを利用する。これらは math.h に含まれており、引数には角度をラジアン単位で渡す必要がある。たとえば、sin(π/2) は1を返すが、sin(90) のように度数で直接渡すと正しい結果が得られない。
#include <stdio.h>
#include <math.h>
int main() {
double degree = 30.0;
double radian = degree * (M_PI / 180.0);
printf("sin(%.1f度) = %.4f\n", degree, sin(radian));
printf("cos(%.1f度) = %.4f\n", degree, cos(radian));
printf("tan(%.1f度) = %.4f\n", degree, tan(radian));
return 0;
}出力
sin(30.0度) = 0.5000
cos(30.0度) = 0.8660
tan(30.0度) = 0.5774角度の単位変換は重要で、度数(degrees)をラジアン(radians)に変換するには次の計算式を使う。
radian = degree × (M_PI / 180.0)ここで M_PI は円周率πを表す定数で、math.h をインクルードすれば利用できる。例えば、30度のサインを求めたい場合は、sin(30 * M_PI / 180.0) と書く。こうすることで、計算結果が正確になる。
三角関数の戻り値は double 型の値で、-1から1の範囲となることが多い。tan() は角度によっては無限大に近づくことがあるため、使用時は角度の範囲に気をつける必要がある。例えば90度や270度のラジアンはタンジェントの定義域外にあたる。
また、逆三角関数として asin()、acos()、atan() も利用可能だ。これらは値から角度を求める関数で、引数はそれぞれ特定の範囲内にある必要がある。戻り値はラジアンで返されるため、度数に戻したい場合は逆に
degree = radian × (180.0 / M_PI)で変換する。
プログラム内で角度の単位を統一して扱うことで、三角関数の計算ミスを防げる。角度の単位に注意し、ラジアン変換を正しく行うことが正確な数学計算の基本である。
対数と指数関数を使った応用的な計算
C言語で対数や指数を計算するときは、log()、log10()、exp() の3つの関数を使う。log() は自然対数を計算し、底は数学でよく使われるネイピア数(約2.718)だ。log10() は常用対数で、底が10となる。exp() は自然対数の底を使った指数関数で、exp(x) は e^x (eのx乗)の値を返す。
#include <stdio.h>
#include <math.h>
int main() {
double value = 10.0;
// 自然対数(底eの対数)
double natural_log = log(value);
// 常用対数(底10の対数)
double common_log = log10(value);
// 指数関数(eのべき乗)
double exponent = exp(2.0); // e^2
printf("log(%.2f) = %.4f\n", value, natural_log);
printf("log10(%.2f) = %.4f\n", value, common_log);
printf("exp(2.0) = %.4f\n", exponent);
return 0;
}log(10.00) = 2.3026
log10(10.00) = 1.0000
exp(2.0) = 7.3891log(10.00) は e ( ≒ 2.71828)を何乗したら 10 になるかを求めている。
log10(10.00) は10 を何回かけたら 10 になるかを求めている。
exp(2.0) は、e( ≒ 2.71828)を 2乗した値を求めている。
使い分けとしては、自然対数は微分や積分、科学計算でよく用いられ、常用対数は桁数計算や対数目盛りで役立つ。例えば、ある数の桁数を求めたいときは log10() を使うと便利だ。
どの関数も引数は正の実数でなければならない。0以下の値を渡すと、実行時にエラーになったり未定義の値が返る可能性がある。安全に使うため、呼び出す前に引数が正かどうかをチェックすることが望ましい。
たとえば次のように条件分岐で処理を分ける。
#include <stdio.h>
#include <math.h>
int main() {
double x;
// ユーザーから値を入力
printf("正の数を入力してください: ");
scanf("%lf", &x);
// log(x) を使う前にチェック
if (x > 0.0) {
double y = log(x); // ln(x)
printf("log(%.4f) = %.4f\n", x, y);
} else {
printf("エラー: log(x) は x > 0 のときのみ計算できます。\n");
}
return 0;
}正の数を入力してください: 4
log(4.0000) = 1.3863正の数を入力してください: -5
エラー: log(x) は x > 0 のときのみ計算できます。exp() は指数を計算するため、たとえば成長モデルや確率計算で頻繁に使われる。exp(0) は1となり、指数関数の基本的な性質も覚えておくと計算ミスを減らせる。
これらの関数を組み合わせれば複雑な数学的処理もC言語で効率よく実装できる。入力値の範囲などに気をつけて利用しよう。
乱数生成とその活用方法:ゲーム・シミュレーション応用
C言語で乱数を生成するには、rand() 関数を使う。これは0から32767までの整数を返すため、そのまま使うと範囲が限定されてしまう。実用的には、乱数を特定の範囲に収める工夫が必要だ。たとえば、0から99までの乱数を得たい場合は次のように書く。
int r = rand() % 100;rand() の結果を 100 で割った余りを取ることで、0から99までの値に変換できる。
一方、srand() は乱数の種(シード)を設定する関数だ。これを使わないと、プログラムを起動するたびに同じ乱数の並びになる。通常は現在時刻を使ってシードを初期化する。例えば、
srand((unsigned int)time(NULL));と書くことで、実行するたびに違った乱数列が生成される。time() を使う場合は のインクルードが必要だ。
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main() {
// 乱数の種を現在時刻で初期化
srand((unsigned int)time(NULL));
// 0~99の乱数を生成
int random_number = rand() % 100;
printf("生成した乱数: %d\n", random_number);
return 0;
}生成した乱数: 68ゲームやシミュレーションでは、こうした乱数を使って動きをランダムにしたり、確率的なイベントを発生させたりする。乱数の範囲設定やシードの初期化を正しく行うことで、期待した動作を実現できる。




