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ライブラリの仕様を確認してください。