HOWTO · C
C の指数
この記事では、C 言語で指数関数を使用する方法を紹介します。
このページの内容
Cでは、浮動小数点数の累乗や負の指数には<math.h>のpow()を使います。非負の整数指数なら、乗算ループを使って結果を整数のまま計算できます。この違いは重要です。pow()の戻り値はdoubleですが、整数ループでは結果を格納する型の範囲を超えることがあります。
Cで累乗を計算する仕組み
累乗では、底を指数の回数だけ掛け合わせます。2^3なら、底は2、指数は3なので、結果は8です。Cには累乗演算子がありません。^はビット単位のXOR演算子です。必要な入力型と結果型に応じて、数学ライブラリの関数を使うか、ループを記述します。
pow(base, exponent)関数は整数を含む算術型の引数を受け取り、戻り値としてdoubleを返します。<math.h>をインクルードすると関数の宣言を利用できます。GCCを一般的なUnix系システムで使う場合など、環境によっては数学ライブラリを-lmでリンクする必要があります。たとえば、gcc powers.c -o powers -lmでコンパイルします。
浮動小数点数の累乗にはpow()を使う
底または指数に小数を使う場合、指数が負になる場合、あるいは結果を浮動小数点数で扱う場合はpow()を使います。たとえば、double result = pow(2.0, 3.0);は浮動小数点数の累乗を計算します。この呼び出しは構文例のみです。実行可能なプログラムで使う場合、ツールチェーンが必要とする環境では数学ライブラリをリンクしてください。
戻り値は浮動小数点数なので、数学的には整数になる答えでも、浮動小数点数の表現や丸めの影響を受けることがあります。表示したい精度に合わせてprintfの書式を選んでください。ビルド時にpowへの未解決参照エラーが出たら、コンパイラで数学ライブラリをリンクする方法を確認します。一般的なUnix系システムでGCCを使う場合は、ソースファイルまたはオブジェクトファイルの後に-lmを置きます。たとえば、gcc powers.c -o powers -lmのように指定します。
ループで非負の整数乗を計算する
入力と求める結果がどちらも整数の場合は、ループを使えば結果を浮動小数点数に変換せずに計算できます。累積値を1で初期化し、指数の回数だけ底を掛けます。
次の完全なプログラムは、乗算ループで2の3乗を計算します。この例を実行してください。
このセクションのコードと表示されるラベルや出力は英語のままです。
#include <stdio.h>
int main(void) {
int base = 2;
int exponent = 3;
int result = 1;
for (int i = 0; i < exponent; ++i) {
result *= base;
}
printf("%d raised to the power of %d is %d\n", base, exponent, result);
return 0;
}
2 raised to the power of 3 is 8
累積値を1から始めるため、指数が0なら乗法単位元である1が返ります。このループが扱うのは非負の整数指数です。乗算を繰り返すので、計算時間は指数に比例します。より大きな指数では、繰り返し二乗法を使うと乗算回数を減らせますが、結果を格納する型の範囲制限はなくなりません。
出力例に表示される文言は、変更されていない例の一部として英語のままです。
方法の選び方と数値範囲の制限
小数または負の指数を扱う場合や、浮動小数点数の結果でよい場合はpow()を使います。たとえば、負の指数は対応する正の累乗の逆数を表すため、pow(2.0, -3.0)は0.125です。整数の結果では小数の逆数を表せないので、上の整数ループはこの計算には適しません。
整数型の幅と値の範囲はCの実装によって異なります。より幅の広い型を使うとオーバーフローを先送りできますが、防ぐことはできません。符号なし整数の演算では、型の最大値に1を足した数を法として値が折り返します。一方、符号付き整数のオーバーフローは、定義された折り返し動作ではないため、それに頼らないでください。結果が選んだ型の範囲を超える可能性がある場合は、適切な表現を選ぶか、乗算前にオーバーフローを検出します。pow()にも特定の入力に対する定義域と値域の条件があります。該当するケースを扱うときは、Cライブラリの仕様を確認してください。