6日でできる 新C言語入門|math.hで学ぶC言語の計算処理

複雑な計算も、数学関数を使えばすっきり書ける。
math.hを活用して、三角関数・平方根・べき乗・丸め処理をC言語で扱えるようになろう。

C言語では、足し算、引き算、掛け算、割り算だけでなく、平方根、べき乗、三角関数、小数の切り上げや切り下げなど、さまざまな計算を行うことができます。

これらの計算を自分で一から作るのは大変です。たとえば、平方根を求める処理や、sin、cos、tanのような三角関数を自力で計算するのは簡単ではありません。

そこで使うのが、数学関数です。

C言語では、数学関数を使うためにmath.hを読み込みます。math.hには、sin、cos、tan、sqrt、pow、fabs、ceil、floorなど、計算でよく使う関数が用意されています。

たとえば、円や角度に関する計算では三角関数を使います。数値の絶対値を求める場合はfabs、平方根を求める場合はsqrt、べき乗を求める場合はpowを使います。小数を切り上げたいときはceil、切り下げたいときはfloorを使います。

この記事では、math.hで使える代表的な数学関数、角度をラジアンへ変換する考え方、絶対値・べき乗・平方根・切り上げ・切り下げの使い方を、サンプルプログラムを通してやさしく解説していきます。

math.hで使える代表的な数学関数

math.hを読み込むと、数学計算に便利な関数を使えるようになります。

#include <math.h>

代表的な関数を整理すると、次のようになります。

関数名役割使用例
sin正弦を求めるsin(radian)
cos余弦を求めるcos(radian)
tan正接を求めるtan(radian)
sqrt平方根を求めるsqrt(25.0)
powべき乗を求めるpow(2.0, 3.0)
fabs実数の絶対値を求めるfabs(-3.5)
ceil小数を切り上げるceil(3.2)
floor小数を切り下げるfloor(3.8)

注意したいのは、absは整数用の絶対値関数で、stdlib.hに用意されています。一方、fabsは実数用の絶対値関数で、math.hに用意されています。

関数名対象必要なヘッダファイル
absint型などの整数stdlib.h
fabsdouble型などの実数math.h

整数と実数で使う関数が違う点は、よく間違えやすいところです。

図:math.hは数学関数をまとめた道具箱

この図から分かること

この図から分かるのは、math.hが数学計算のための関数をまとめたヘッダファイルだということです。

三角関数、平方根、べき乗、実数の絶対値、小数の切り上げや切り下げなどは、math.hの関数を使うことで短く分かりやすく書けます。計算処理が複雑になるほど、標準ライブラリの関数を使うメリットが大きくなります。

三角関数ではラジアンを使う

sin、cos、tanのような三角関数では、角度をラジアンで指定します。

普段の生活では、角度を30度、45度、90度のような度数法で表すことが多いです。しかし、C言語の三角関数にそのまま30や45を渡しても、30度や45度として扱われるわけではありません。

三角関数に渡す値はラジアンです。

度数法をラジアンへ変換する式は、次のようになります。

radian = degree * PI / 180.0;

ここでPIは円周率を表します。

C言語の標準規格では、環境によってPIという定数が最初から使えるとは限りません。そのため、学習用のプログラムでは自分でPIを定義しておくと分かりやすくなります。

#define PI 3.141592653589793

このように定義しておけば、度数法からラジアンへの変換を分かりやすく書けます。

度数法とラジアンの関係

度数法とラジアンの対応を表にすると、次のようになります。

度数法ラジアンの目安よく使う場面
0度0基準の角度
30度約0.5236三角関数の基本
45度約0.7854直角二等辺三角形
60度約1.0472正三角形
90度約1.5708直角
180度約3.1416半周

C言語のsin、cos、tanを使うときは、度数法をラジアンへ変換してから渡す、と覚えておきましょう。

度数を入力して三角関数を計算するプログラム

次のプログラムでは、角度を度数法で入力し、ラジアンへ変換してからsin、cos、tanの値を表示します。

プロジェクト/ファイル名: Lesson47_1/main.c

#include <stdio.h>
#include <math.h>

#define PI 3.141592653589793

// 度数法の角度をラジアンへ変換する関数
double toRadian(double degree) {
    return degree * PI / 180.0;
}

int main(void) {
    double degree;
    double radian;

    printf("角度を度数法で入力してください: ");
    scanf("%lf", °ree);

    // 入力された角度をラジアンへ変換する
    radian = toRadian(degree);

    printf("%.2f度は %.4f ラジアンです。\n", degree, radian);
    printf("sinの値は %.4f です。\n", sin(radian));
    printf("cosの値は %.4f です。\n", cos(radian));
    printf("tanの値は %.4f です。\n", tan(radian));

    return 0;
}

実行結果

角度を度数法で入力してください: 45
45.00度は 0.7854 ラジアンです。
sinの値は 0.7071 です。
cosの値は 0.7071 です。
tanの値は 1.0000 です。

このプログラムでは、最初にPIを定義しています。

#define PI 3.141592653589793

次に、toRadian関数で度数法の角度をラジアンへ変換しています。

double toRadian(double degree) {
    return degree * PI / 180.0;
}

main関数では、入力された角度をtoRadian関数へ渡し、ラジアンの値を求めています。

そのあと、sin、cos、tanにラジアンの値を渡して、それぞれの値を表示しています。

Visual Studioでscanfを使う場合、環境設定によって警告が表示されることがあります。学習用として動作確認する場合は、必要に応じてSDLチェックの設定も確認しておきましょう。

図:度数法をラジアンに変換して三角関数へ渡す

この図から分かること

この図から分かるのは、C言語の三角関数では、角度をそのまま度数法で渡すのではなく、ラジアンへ変換してから使う必要があるということです。

45度のような普段見慣れた角度は、toRadian関数のような変換処理を通してラジアンに変換します。そのラジアン値をsin、cos、tanに渡すことで、期待した三角関数の値を求められます。

絶対値・べき乗・平方根を使う

math.hには、三角関数以外にも便利な関数があります。

特によく使うのが、絶対値、べき乗、平方根です。

関数名役割
abs整数の絶対値を求めるabs(-12)
fabs実数の絶対値を求めるfabs(-12.5)
powべき乗を求めるpow(2.0, 3.0)
sqrt平方根を求めるsqrt(16.0)

absはstdlib.hで使えます。整数の絶対値を求めるときに使います。

fabsはmath.hで使えます。小数を含む実数の絶対値を求めるときに使います。

powは、べき乗を求める関数です。たとえば2の3乗はpow(2.0, 3.0)で求められます。

sqrtは、平方根を求める関数です。たとえば16の平方根はsqrt(16.0)で求められます。

整数用のabsと実数用のfabsを使い分ける

絶対値を求める関数には、absとfabsがあります。

名前が似ていますが、対象が違います。

関数名対象戻り値の例
abs整数-8を8にする
fabs実数-4.2を4.2にする

整数にはabs、実数にはfabsを使うと覚えておくと分かりやすいです。

小数を含む値にabsを使うと、期待した結果にならないことがあります。実数の絶対値にはfabsを使いましょう。

絶対値・べき乗・平方根を確認するプログラム

次のプログラムでは、整数の絶対値、実数の絶対値、正方形の面積、平方根を計算します。

プロジェクト/ファイル名: Lesson47_2/main.c

#include <stdio.h>
#include <stdlib.h>
#include <math.h>

int main(void) {
    int diff = -18;
    double temperatureDiff = -6.75;
    double side = 4.5;
    double area;
    double diagonal;

    // 整数の絶対値を求める
    printf("整数差 %d の絶対値は %d です。\n", diff, abs(diff));

    // 実数の絶対値を求める
    printf("温度差 %.2f の絶対値は %.2f です。\n", temperatureDiff, fabs(temperatureDiff));

    // べき乗を使って正方形の面積を求める
    area = pow(side, 2.0);
    printf("一辺 %.2f の正方形の面積は %.2f です。\n", side, area);

    // 平方根を使って正方形の対角線の長さを求める
    diagonal = sqrt(pow(side, 2.0) + pow(side, 2.0));
    printf("一辺 %.2f の正方形の対角線は %.2f です。\n", side, diagonal);

    return 0;
}

実行結果

整数差 -18 の絶対値は 18 です。
温度差 -6.75 の絶対値は 6.75 です。
一辺 4.50 の正方形の面積は 20.25 です。
一辺 4.50 の正方形の対角線は 6.36 です。

このプログラムでは、整数diffに対してabsを使っています。

abs(diff)

実数temperatureDiffに対してはfabsを使っています。

fabs(temperatureDiff)

また、powを使ってsideの2乗を求めています。

area = pow(side, 2.0);

正方形の対角線は、ピタゴラスの定理を使って求めています。

一辺がsideの正方形では、対角線の長さは次の式で求められます。

sqrt(pow(side, 2.0) + pow(side, 2.0))

このように、powとsqrtを組み合わせると、図形に関する計算も分かりやすく書けます。

pow関数とsqrt関数の戻り値はdouble型

powとsqrtは、基本的にdouble型の値を扱います。

たとえば、次のように整数っぽい値を渡しても、結果はdouble型として扱うと考えると分かりやすいです。

pow(5.0, 2.0)
sqrt(25.0)

printfで表示するときは、小数用の書式指定子を使います。

printf("%.2f\n", sqrt(25.0));

整数として表示したい場合は、キャストや丸め処理を考える必要があります。ただし、学習段階では、数学関数の戻り値はdouble型として扱うと覚えておくと安全です。

小数の切り上げ・切り下げを使う

小数を整数方向へ丸めたい場面では、ceilやfloorが便利です。

関数名役割
ceil小数を切り上げるceil(3.2)は4.0
floor小数を切り下げるfloor(3.8)は3.0

ceilは、指定した値以上の最小の整数値へ切り上げます。

floorは、指定した値以下の最大の整数値へ切り下げます。

どちらも戻り値はdouble型です。そのため、表示するときは%.0fや%.2fのような小数用の書式を使います。

切り上げ・切り下げを確認するプログラム

次のプログラムでは、商品の重さから必要な箱の数を計算します。1箱に入れられる重さを2.5kgとして、必要な箱数を切り上げで求めます。また、floorを使って小数部分を切り下げた値も確認します。

プロジェクト/ファイル名: Lesson47_3/main.c

#include <stdio.h>
#include <math.h>

int main(void) {
    double totalWeight = 9.3;
    double boxLimit = 2.5;
    double exactBoxes;
    double requiredBoxes;
    double lowerBoxes;

    // 必要な箱数を小数で計算する
    exactBoxes = totalWeight / boxLimit;

    // 実際に必要な箱数は切り上げる
    requiredBoxes = ceil(exactBoxes);

    // 切り下げた場合の値も確認する
    lowerBoxes = floor(exactBoxes);

    printf("合計重量: %.2f kg\n", totalWeight);
    printf("1箱あたりの上限: %.2f kg\n", boxLimit);
    printf("計算上の箱数: %.2f 箱\n", exactBoxes);
    printf("切り上げた箱数: %.0f 箱\n", requiredBoxes);
    printf("切り下げた箱数: %.0f 箱\n", lowerBoxes);

    return 0;
}

実行結果

合計重量: 9.30 kg
1箱あたりの上限: 2.50 kg
計算上の箱数: 3.72 箱
切り上げた箱数: 4 箱
切り下げた箱数: 3 箱

このプログラムでは、まず必要な箱数を小数で計算しています。

exactBoxes = totalWeight / boxLimit;

9.3kgを1箱2.5kgで分けると、3.72箱になります。

しかし、箱は3.72箱のように小数では用意できません。実際には4箱必要です。

そこでceilを使って切り上げています。

requiredBoxes = ceil(exactBoxes);

floorを使うと、3.72を3.0に切り下げます。

lowerBoxes = floor(exactBoxes);

このように、実生活に近い計算では、切り上げや切り下げがとても役立ちます。

図:計算目的に合わせて数学関数を選ぶ

この図から分かること

この図から分かるのは、計算したい内容によって使う数学関数が変わるということです。

絶対値ならabsやfabs、べき乗ならpow、平方根ならsqrt、小数の切り上げならceil、切り下げならfloorを使います。関数の役割を整理しておくと、必要な計算に合った関数を選びやすくなります。

マクロで角度変換を分かりやすくする

角度変換はよく使う処理なので、マクロにしておく方法もあります。

#define PI 3.141592653589793
#define DEG2RAD(x) ((x) * PI / 180.0)

このように定義しておくと、度数法の角度をラジアンに変換しながら三角関数へ渡せます。

sin(DEG2RAD(60.0))

マクロを使うと短く書けますが、式の中で使う場合に思わぬ計算順序にならないよう、引数や全体を丸かっこで囲むことが大切です。

#define DEG2RAD(x) ((x) * PI / 180.0)

このように書くと、計算順序のトラブルを防ぎやすくなります。

math.hを使うときの注意点

math.hを使うときは、次の点に注意しましょう。

注意点内容
math.hを読み込むsin、cos、sqrt、powなどを使うために必要
三角関数はラジアン指定度数法の角度はラジアンへ変換する
absとfabsを使い分ける整数はabs、実数はfabs
戻り値はdouble型が多い表示には%.2fなどを使う
環境によってリンク設定が必要な場合があるVisual Studioでは通常そのまま使えることが多い

特に三角関数で度数法をそのまま渡してしまうミスはよくあります。

たとえば、sin(90.0)と書くと、90度のsinを求めているつもりでも、実際には90ラジアンとして扱われます。90度のsinを求めたい場合は、90度をラジアンへ変換してから渡します。

math.hの関数を使うと計算処理が読みやすくなる

math.hを使うと、C言語でさまざまな数学計算を簡単に書けます。

三角関数にはsin、cos、tanを使います。ただし、これらの関数にはラジアンを渡す必要があります。度数法で入力した角度を使いたい場合は、degree * PI / 180.0のような式でラジアンへ変換します。

絶対値では、整数ならabs、実数ならfabsを使います。べき乗はpow、平方根はsqrtを使うことで、図形や数値計算を短く表現できます。

小数の丸め処理では、ceilで切り上げ、floorで切り下げができます。箱の数や人数、料金の段階計算など、実用的な場面でも役立ちます。

数学関数を使いこなせるようになると、計算処理を自分で複雑に書かなくても、標準ライブラリの力を使って分かりやすいプログラムを作れるようになります。