【C言語】N乗根を求める方法

C言語でN乗根を求める方法の解説ページアイキャッチ

このページでは、C言語での「N 乗根の求め方」について解説します!

下記ページで解説しているとおり、sqrt 関数を利用することで2乗根(平方根)を、cbrt 関数を利用することで3乗根(立方根)をそれぞれ求めることが可能です。

sqrt関数とcbrt関数の解説ページアイキャッチ【C言語】sqrt関数で平方根・cbrt関数で立方根を求める(ルート計算)

ただし、これらの関数で求めることができるのは指数を「23 とした場合の冪根」のみであり、他の値を指数とする冪根は求められません。

では、他の値を指数とする冪根、すなわち「N 乗根」を求めるにはどうすれば良いのでしょうか?

この点について、ここから解説していきたいと思います。

pow 関数を利用して N 乗根を求める

結論としては、pow 関数を利用すれば N 乗根を求めることが可能です。

pow 関数を利用した N 乗根の求め方

pow 関数の詳細は下記ページで解説していますが、要は冪乗(べき乗)を求める関数であり、pow(x, n) を実行することで xn 乗の値を返却値として得ることができます。

C言語でべき乗計算および累乗計算を行う方法の解説ページアイキャッチ【C言語】べき乗計算・累乗計算を行う方法(pow関数)

この第2引数 n には整数だけでなく実数を指定することが可能です。

さらに、数 x に対する N 乗根は x1 / N 乗することで求めることが可能です。

$$ \sqrt[N]{ x } = x^{ \frac {1}{N} } $$

したがって、pow 関数の第2引数 n1 / N を指定してやれば、第1引数 x に指定した値の N 乗根を求めることができることになります。

pow関数でN乗根を求める

double ans = pow(x, (double)1 / (double)N);

pow 関数利用時は math.h をインクルードしておく必要があるので注意してください。

(double) でキャストしている理由については後述の pow 関数を利用して N 乗根を求める際の注意点 で解説しています。

スポンサーリンク

pow 関数を利用して N 乗根を求める例

下記は、pow 関数を利用して xN 乗根を求める例となります。

1行目で N = 7 を行っているので、x7 乗根が求められることになります。N の値を変更することで、N = 7 以外の時の N 乗根を求めることも可能です(N はもちろん #define 等で定義しても良いです)。

pow関数でN乗根を求める例

int N = 7;

double x = 3.5;
double n = (double)1 / (double)N;

double ans = pow(x, n);

printf("ans = %f\n", ans);

printf("%f : %f\n", x, pow(ans, N));

実行すれば、下記のような結果が得られます。

ans = 1.195980
3.500000 : 3.500000

1行目に出力されるのが pow 関数の結果となる ans の値となります。これだけ見ても、N 乗根が求められているか分かりにくいですね…。

ただ、2行目では左側に x 、右側に ans を N 乗した値を出力しており、ans を N 乗した値が x と同じ値になっていることから、ansx の N 乗根の値になっていること、すなわち pow 関数から N 乗根を求めることができていることが確認できると思います。

補足しておくと、2行目の左側と右側の値は同じ値が出力されていますが、実際には誤差による差があります。これは、下記ページで紹介しているように printf で出力する小数点以下の桁数を増やすことで確認することができます。

printfで小数点以下の桁をたくさん表示する方法の解説ページアイキャッチ【C言語】printfで小数点以下の桁をたくさん表示する方法

pow 関数を利用して N 乗根を求める際の注意点

続いて、簡単に pow 関数で N 乗根を求める際の注意点について説明しておきます。

指数の計算に注意

pow 関数に限った話ではないのですが、pow 関数に第2引数で指定する「指数の計算」に注意してください。

N 乗根を求める際には 1 / Npow 関数の第2引数に指定することになりますが、N が整数である場合、1 / N を単純に計算してしまうと 0 になってしまう可能性があるので注意してください。

例えば下記のように pow 関数を実行してしまうと、pow 関数の返却値は x7 乗根ではなく 1 になってしまいます。これは、pow 関数の第2引数に指定する 1 / 7 の結果が 0 になってしまうからです(x0 乗は 1 になる)。

powでN乗根が求められない例

double ans = pow(x, 1 / 7);

1 / 70 になってしまうのは、整数 / 整数 の除算結果が整数として扱われるからです。整数として扱われるため、除算結果の小数点以下の値が切り捨てられて結果が 0 となってしまいます。

除算結果の小数点以下の値も含めて pow 関数の第2引数に指定するためには、キャストを利用して除数と被除数のいずれか、もしくは両方を浮動小数点数として扱うようにしてから除算を行う必要があります。

具体的には、下記のように整数(or 整数型の変数)の前に (double)(float) 等を付けてやれば良いです。

powで正常にN乗根が求められる例1

double ans = pow(x, (double)1 / (double)7);

これにより、整数 / 整数 ではなく 浮動小数点数 / 浮動小数点数 として計算が行われるようになります。そして、計算結果も 浮動小数点数 として扱われ、小数点以下の値も pow 関数の第2引数として渡すことができます。

また、下記のように、被除数を浮動小数点数として扱われるように 1.0 とするのでも良いです。

powで正常にN乗根が求められる例2

double ans = pow(x, 1.0 / 7);

特に N 乗根を求める場合は、N を整数とする場合が多いと思います。

この場合、前述のように pow の第2引数を単に 1 / N としてしまい、結果が 1 になってしまうバグに陥りやすいです。そのため、特に pow 関数で N 乗根を求める際には第2引数の計算の仕方に注意してください。

この例のように、C言語で計算結果が意図しないものになる場合は型が原因であることが多いです。その他の例も下記ページでいくつか紹介していますので、興味があれば是非読んでみてください。

【C言語】計算結果がおかしい時の対処法まとめ

返却値は1つのみ

下記ページの sqrt の解説でも説明していますが、2乗根等の指数 N が偶数である場合の N 乗根 は2つ存在することになります(N = 0 を除く)。

ですが、pow 関数が返却するのはそのうちの1つのみ、具体的には正の方の解のみが返却されることになります。

sqrt関数とcbrt関数の解説ページアイキャッチ【C言語】sqrt関数で平方根・cbrt関数で立方根を求める(ルート計算)

N 乗根を2つとも表示したいような場合は、pow 関数の呼び出し側で返却値の符号を反転するなどの処理が別途必要になります。

exp 関数と log を利用して N 乗根を求める

pow 関数だけでなく、exp 関数と log 関数を利用して N 乗根を求めることも可能です。

スポンサーリンク

exp 関数と log 関数を利用した N 乗根の求め方

Wikipedia の 指数関数のページ を見ていただければわかる通り、下記のように \( a \) の \( n \) 乗はネイピア数 \( e \) の冪乗で表すことが可能です。

$$ a^{ n } = e^{n \log_{e} a }$$

ここで、\( a \) を \( x \)、\( n \) を \( 1 / N \) とすれば、下記の等式が成立することになります。

$$ x^{ \frac {1}{N} } = e^{\frac {1}{N} \log_{e} x }$$

pow 関数を利用して N 乗根を求める で解説したように、上式の左辺では \( x \) の \( N \) 乗根を求めることができますので、つまりは上式の右辺を計算することで、\( x \) の \( N \) 乗根を求めることができることになります。

で、下記ページで解説しているとおり、C言語では \( e \) の冪乗は exp 関数で求めることが可能です。

exp関数の使い方の解説ページアイキャッチ【C言語】exp 関数で「ネイピア数を扱う」&「e の x 乗を求める」

さらに、下記ページで解説しているとおり、\( \log_{e} x \)、すなわち \( e \) を底とする \( x \) の対数は log 関数で求めることが可能です。

C言語での対数の求め方の解説ページアイキャッチ【C言語】log・log2・log10 関数で対数を求める

したがって、xN 乗根は、exp 関数と log 関数を利用して下記の処理で求めることができます。

exp関数とlog関数でN乗根を求める

double ans = exp((double)1 / (double)N * log(x));

exp 関数と log 関数ともに、利用時は math.h をインクルードしておく必要があるので注意してください。

また、解説は省略させていただきますが、exp 関数と log 関数で N 乗根を求める際にも pow 関数を利用して N 乗根を求める際の注意点 で解説した内容が当てはまりますので注意してください。

exp 関数と log 関数を利用して N 乗根を求める例

下記は、exp 関数と log 関数を利用して xN 乗根を求める例となります。

pow 関数を利用して N 乗根の求める例 の時同様に、N = 7 として N 乗根を求めています。

exp関数とlog関数でN乗根を求める例

int N = 7;

double x = 50;
double n = (double)1 / (double)N;

double exp_ans = exp(n * log(x));
double pow_ans = pow(x, n);

printf("exp_ans = %f\n", exp_ans);
printf("pow_ans = %f\n", pow_ans);

実行すると下記のように結果が表示されます。

exp_ans = 1.748679
pow_ans = 1.748679

1行目では exp 関数と log 関数で N 乗根を求めた結果を出力し、2行目では pow 関数で N 乗根を求めた結果を出力しています。

同じ値が出力されており、exp 関数と log 関数からでも N 乗根が求められることを確認できると思います(ただし、実際には誤差が発生するため2つの値には差があります)。

まとめ

このページでは、C言語での「N 乗根の求め方」について解説しました!

C言語では、N 乗根は下記によって求めることが可能です(求める方法は他にもあります)。

  • pow 関数を利用する
  • exp 関数と log 関数を利用する

平方根(2乗根)を求める機会はそれなりに多いと思いますが、それ以外の N 乗根を求める機会はそんなに多くないんじゃないかなぁと思います。

逆にいうと、N 乗根を求める機会が少ない分、N 乗根の求め方は覚えにくいです。とりあえず、pow 関数で冪乗だけでなく冪根も求めることができることは頭の隅にでも置いておきましょう!

オススメの参考書

C言語学習中だけど分からないことが多くて挫折しそう...という方には、下記の「スッキリわかるC言語入門」がオススメです!

まず学習を進める上で、参考書は2冊持っておくことをオススメします。この理由は下記の2つです。

  • 参考書によって、解説の仕方は異なる
  • 読み手によって、理解しやすい解説の仕方は異なる

ある人の説明聞いても理解できなかったけど、他の人からちょっと違った観点での説明を聞いて「あー、そういうことね!」って簡単に理解できた経験をお持ちの方も多いのではないでしょうか?

それと同じで、1冊の参考書を読んで理解できない事も、他の参考書とは異なる内容の解説を読むことで理解できる可能性があります。

なので、参考書は2冊持っておいた方が学習時に挫折しにくいというのが私の考えです。

特に上記の「スッキリわかるC言語入門」は、他の参考書とは違った切り口での解説が豊富で、他の参考書で理解できなかった内容に対して違った観点での解説を読むことができ、オススメです。題名の通り「なぜそうなるのか?」がスッキリ理解できるような解説内容にもなっており、C言語入門書としてもかなり分かりやすい参考書だと思います。

もちろんネット等でも色んな観点からの解説を読むことが出来ますので、分からない点は別の人・別の参考書の解説を読んで解決していきましょう!もちろん私のサイトも参考にしていただけると嬉しいです!

入門用のオススメ参考書は下記ページでも紹介していますので、こちらも是非参考にしていただければと思います。

https://daeudaeu.com/c_reference_book/

同じカテゴリのページ一覧を表示