このページでは、C言語での「N
乗根の求め方」について解説します!
下記ページで解説しているとおり、sqrt
関数を利用することで2乗根(平方根)を、cbrt
関数を利用することで3乗根(立方根)をそれぞれ求めることが可能です。
ただし、これらの関数で求めることができるのは指数を「2
や 3
とした場合の冪根」のみであり、他の値を指数とする冪根は求められません。
では、他の値を指数とする冪根、すなわち「N
乗根」を求めるにはどうすれば良いのでしょうか?
この点について、ここから解説していきたいと思います。
Contents
pow
関数を利用して N
乗根を求める
結論としては、pow
関数を利用すれば N
乗根を求めることが可能です。
pow
関数を利用した N
乗根の求め方
pow
関数の詳細は下記ページで解説していますが、要は冪乗(べき乗)を求める関数であり、pow(x, n)
を実行することで x
の n
乗の値を返却値として得ることができます。
この第2引数 n
には整数だけでなく実数を指定することが可能です。
さらに、数 x
に対する N
乗根は x
を 1 / N
乗することで求めることが可能です。
$$ \sqrt[N]{ x } = x^{ \frac {1}{N} } $$
したがって、pow
関数の第2引数 n
に 1 / N
を指定してやれば、第1引数 x
に指定した値の N
乗根を求めることができることになります。
double ans = pow(x, (double)1 / (double)N);
pow
関数利用時は math.h
をインクルードしておく必要があるので注意してください。
(double)
でキャストしている理由については後述の pow 関数を利用して N 乗根を求める際の注意点 で解説しています。
スポンサーリンク
pow
関数を利用して N
乗根を求める例
下記は、pow
関数を利用して x
の N
乗根を求める例となります。
1行目で N = 7
を行っているので、x
の 7
乗根が求められることになります。N
の値を変更することで、N = 7
以外の時の N
乗根を求めることも可能です(N
はもちろん #define
等で定義しても良いです)。
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
と同じ値になっていることから、ans
が x
の N
乗根の値になっていること、すなわち pow
関数から N
乗根を求めることができていることが確認できると思います。
補足しておくと、2行目の左側と右側の値は同じ値が出力されていますが、実際には誤差による差があります。これは、下記ページで紹介しているように printf
で出力する小数点以下の桁数を増やすことで確認することができます。
pow
関数を利用して N
乗根を求める際の注意点
続いて、簡単に pow
関数で N
乗根を求める際の注意点について説明しておきます。
指数の計算に注意
pow
関数に限った話ではないのですが、pow
関数に第2引数で指定する「指数の計算」に注意してください。
N
乗根を求める際には 1 / N
を pow
関数の第2引数に指定することになりますが、N
が整数である場合、1 / N
を単純に計算してしまうと 0
になってしまう可能性があるので注意してください。
例えば下記のように pow
関数を実行してしまうと、pow
関数の返却値は x
の 7
乗根ではなく 1
になってしまいます。これは、pow
関数の第2引数に指定する 1 / 7
の結果が 0
になってしまうからです(x
の 0
乗は 1
になる)。
double ans = pow(x, 1 / 7);
1 / 7
が 0
になってしまうのは、整数 / 整数
の除算結果が整数として扱われるからです。整数として扱われるため、除算結果の小数点以下の値が切り捨てられて結果が 0
となってしまいます。
除算結果の小数点以下の値も含めて pow
関数の第2引数に指定するためには、キャストを利用して除数と被除数のいずれか、もしくは両方を浮動小数点数として扱うようにしてから除算を行う必要があります。
具体的には、下記のように整数(or 整数型の変数)の前に (double)
や (float)
等を付けてやれば良いです。
double ans = pow(x, (double)1 / (double)7);
これにより、整数 / 整数
ではなく 浮動小数点数 / 浮動小数点数
として計算が行われるようになります。そして、計算結果も 浮動小数点数
として扱われ、小数点以下の値も pow
関数の第2引数として渡すことができます。
また、下記のように、被除数を浮動小数点数として扱われるように 1.0
とするのでも良いです。
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つのみ、具体的には正の方の解のみが返却されることになります。
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
関数で求めることが可能です。
さらに、下記ページで解説しているとおり、\( \log_{e} x \)、すなわち \( e \) を底とする \( x \) の対数は log
関数で求めることが可能です。
したがって、x
の N
乗根は、exp
関数と log
関数を利用して下記の処理で求めることができます。
double ans = exp((double)1 / (double)N * log(x));
exp
関数と log
関数ともに、利用時は math.h
をインクルードしておく必要があるので注意してください。
また、解説は省略させていただきますが、exp
関数と log
関数で N
乗根を求める際にも pow 関数を利用して N 乗根を求める際の注意点 で解説した内容が当てはまりますので注意してください。
exp
関数と log
関数を利用して N
乗根を求める例
下記は、exp
関数と log
関数を利用して x
の N
乗根を求める例となります。
pow 関数を利用して N 乗根の求める例 の時同様に、N = 7
として 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
関数で冪乗だけでなく冪根も求めることができることは頭の隅にでも置いておきましょう!
オススメの参考書(PR)
C言語学習中だけど分からないことが多くて挫折しそう...という方には、下記の「スッキリわかるC言語入門」がオススメです!
まず学習を進める上で、参考書は2冊持っておくことをオススメします。この理由は下記の2つです。
- 参考書によって、解説の仕方は異なる
- 読み手によって、理解しやすい解説の仕方は異なる
ある人の説明聞いても理解できなかったけど、他の人からちょっと違った観点での説明を聞いて「あー、そういうことね!」って簡単に理解できた経験をお持ちの方も多いのではないでしょうか?
それと同じで、1冊の参考書を読んで理解できない事も、他の参考書とは異なる内容の解説を読むことで理解できる可能性があります。
なので、参考書は2冊持っておいた方が学習時に挫折しにくいというのが私の考えです。
特に上記の「スッキリわかるC言語入門」は、他の参考書とは違った切り口での解説が豊富で、他の参考書で理解できなかった内容に対して違った観点での解説を読むことができ、オススメです。題名の通り「なぜそうなるのか?」がスッキリ理解できるような解説内容にもなっており、C言語入門書としてもかなり分かりやすい参考書だと思います。
もちろんネット等でも色んな観点からの解説を読むことが出来ますので、分からない点は別の人・別の参考書の解説を読んで解決していきましょう!もちろん私のサイトも参考にしていただけると嬉しいです!
入門用のオススメ参考書は下記ページでも紹介していますので、こちらも是非参考にしていただければと思います。
https://daeudaeu.com/c_reference_book/