ホームC言語Tips集数学 ≫ 立方根を計算する

C言語Tips集 - 立方根を計算する

C言語で立方根を計算する最も簡単な方法は,math.hcbrt 関数,cbrtf 関数,cbrtl 関数のいずれかを使用する方法です.

cbrt 関数,cbrtf 関数,cbrtl 関数はいずれも立方根を計算する関数ですが,引数および戻り値の型がそれぞれ異なります.詳しくは以下をご覧下さい.

#include <math.h>

cbrt (C99)

double cbrt(double x);

cbrtf (C99)

float cbrtf(float x);

cbrtl (C99)

long double cbrtl(long double x);

ただし,cbrt 関数,cbrtf 関数,cbrtl 関数はいずれも C99 で規定されている関数です.
コンパイラが C99 に対応していなかったり,コーディング規約上 C99 を禁止している場合は,他の方法で立方根を求める必要があります.そこで,ここでは cbrt 系の関数を使わずに立方根を求める簡単な方法を 2 種類紹介します.

方法1. 1/3乗を計算する

x の立方根は x を 1/3 乗した値ですので,これを利用します.
具体的には math.hpow 関数を使用して,以下のように記述します.

pow(x, 1.0 / 3.0);

ただし,1/3 は無限循環小数 (0.3333...) になりますので,あまりよい精度では計算できないのが欠点です.

方法2. ニュートン法 (Newton's method) を使って計算する

ニュートン法 (Newton's method) は関数のゼロ点を探すアルゴリズムです.
例えば a の立方根は,3 乗すると a になる数ですので,関数 f(x) = x * x * x - a = 0 と考えてニュートン法で近似します.具体的には以下のように記述します.
(以下は a の立方根を求める関数であることに注意してください.引数 x には a の値に応じて,解に近そうな値を渡します.)

/**
 * ニュートン法で立方根を近似する
 * @param[in] a 実数
 * @param[in] x 解に近そうな値
 * @return a の立方根
 */
double cbrt_newton(double a, double x) {
    double e;

    do {
        e = (x * x * x - a) / (3.0 * x * x);
        x = x - e;
    } while ( fabs(e) > 1.0e-16 );

    return x;
}

C言語サンプルプログラム

以下に立方根を cbrt 関数で求めた場合,1/3 乗を計算した場合,ニュートン法で計算した場合のサンプルプログラムを示します.

/* header files */
#include <stdio.h>
#include <stdlib.h>
#include <math.h>

/* functions */
double cbrt_simple(double x);
double cbrt_newton(double a, double x);

/* main */
int main(void) {
    double x2 = 2.0 * 2.0 * 2.0;
    double x3 = 3.0 * 3.0 * 3.0;
    double x4 = 4.0 * 4.0 * 4.0;
    double x5 = 5.0 * 5.0 * 5.0;

    printf("%.1fの立方根 (真値 = 2.0)\n", x2);
    printf("cbrt:   %.16f\n", cbrt(x2));
    printf("1/3:    %.16f\n", cbrt_simple(x2));
    printf("Newton: %.16f\n", cbrt_newton(x2, 10.0));

    printf("\n%.1fの立方根 (真値 = 3.0)\n", x3);
    printf("cbrt:   %.16f\n", cbrt(x3));
    printf("1/3:    %.16f\n", cbrt_simple(x3));
    printf("Newton: %.16f\n", cbrt_newton(x3, 10.0));

    printf("\n%.1fの立方根 (真値 = 4.0)\n", x4);
    printf("cbrt:   %.16f\n", cbrt(x4));
    printf("1/3:    %.16f\n", cbrt_simple(x4));
    printf("Newton: %.16f\n", cbrt_newton(x4, 10.0));

    printf("\n%.1fの立方根 (真値 = 5.0)\n", x5);
    printf("cbrt:   %.16f\n", cbrt(x5));
    printf("1/3:    %.16f\n", cbrt_simple(x5));
    printf("Newton: %.16f\n", cbrt_newton(x5, 10.0));

    return EXIT_SUCCESS;
}

/**
 * 1/3乗をして立方根を求める
 * @param[in] x 実数
 * @return x の立方根
 */
double cbrt_simple(double x) {
    return pow(x, 1.0 / 3.0);
}

/**
 * ニュートン法で立方根を近似する
 * @param[in] a 実数
 * @param[in] x 解に近そうな値
 * @return a の立方根
 */
double cbrt_newton(double a, double x) {
    double e;

    do {
        e = (x * x * x - a) / (3.0 * x * x);
        x = x - e;
    } while ( fabs(e) > 1.0e-16 );

    return x;
}

実行例

サンプルプログラムの実行結果は以下のようになります.

8.0の立方根 (真値 = 2.0)
cbrt:   2.0000000000000000
1/3:    2.0000000000000000
Newton: 2.0000000000000000

27.0の立方根 (真値 = 3.0)
cbrt:   3.0000000000000000
1/3:    3.0000000000000000
Newton: 3.0000000000000000

64.0の立方根 (真値 = 4.0)
cbrt:   4.0000000000000000
1/3:    3.9999999999999996
Newton: 4.0000000000000000

125.0の立方根 (真値 = 5.0)
cbrt:   5.0000000000000000
1/3:    4.9999999999999991
Newton: 5.0000000000000000

Cプログラマの必読書

たくさんあるC言語関連の書籍の中でも特に役に立った本です.よかったら参考にしてみてください.

C実践プログラミング 第3版

C言語の実践的参考書.少々値段は張りますが初心者を脱しようとしている人は絶対に読むべきです.
文法だけでなく,コーディングスタイルやデバッグなど文字通り「実践的」なことが書かれているので非常にためになります. オライリーの本は,読みにくい本が多いのですが本書はとても読みやすくオススメです.


C言語ポインタ完全制覇 (標準プログラマーズライブラリ)

ポインタの解説書としては最高の書籍です.
この1冊でポインタを完全に理解することができます.全くの初学者が読むには敷居が高いですが,入門書を読み終えた後に読むと非常に有益です.

指数・対数