以下は目次です。
ある数のべき乗(累乗)を求めたいとします。
べき乗の計算では、結果が非常に巨大な数になることがあるため、使っている型で表現しきれなくなることがあります。こういったエラーをきちんと検出できるように関数化してみます。
/*
べき乗を求める
引数
x: 底
y: 指数
result: x を y乗した結果を受け取るメモリアドレス。ヌルポインタは不可。
戻り値
成否。false が返された場合、result の内容は不定。
注意
x、y がともに 0 の場合の結果は 1 とする。
*/
bool power(double x, double y, double* result);
また、0 の 0乗は、文脈によって定義が異なるので(参考リンク1)、結果を明確に決めておいた方がいいでしょう。ここでは、1 を返すことにします。
標準ライブラリには、べき乗を求める pow関数と、その型違いのバージョンがあります。
double pow(double x, double y);
float powf(float x, float y);
long double powl(long double x, long double y);
それぞれ、x の y乗を計算して、結果を戻り値で返します。
整数型のものがないので、整数のべき乗を求めるのなら、基本的には pow関数を選ぶことになります。
【上級】結果を整数型にしなければならないのなら、丸め関数(第48章)を検討しましょう。普通に整数型へ型変換した場合に、変換後の型で表現できないと、未定義の動作になってしまいます(第21章)。
ごく単純には、次のように使えます。
double x = pow(2.0, 3.0); // 2 の 3乗
この例のように、結果が確実に表現でき、エラーが起こる余地がない使い方なら良いのですが、そうでないなら備えが必要です。
pow系の関数は、以下の場合にエラーを発生させます。
数学系関数が発生させるエラーについての詳細は、第48章を参照してください。ここでは、これらのエラーを検出するように関数化します。
#include <assert.h>
#include <errno.h>
#include <float.h>
#include <math.h>
#include <stdbool.h>
#include <stdio.h>
/*
べき乗を求める
引数
x: 底
y: 指数
result: x を y乗した結果を受け取るメモリアドレス。ヌルポインタは不可。
戻り値
成否。false が返された場合、result の内容は不定。
注意
x、y がともに 0 の場合の結果は 1 とする。
*/
bool power(double x, double y, double* result)
{
(result != NULL);
assert
if (x == 0.0 && y == 0.0) {
*result = 1.0;
return true;
}
= 0;
errno *result = pow(x, y);
if (errno == EDOM) {
return false;
}
else if (errno == ERANGE) {
return false;
}
return true;
}
int main(void)
{
double result;
if (power(2.0, 4.0, &result)) {
("%lf\n", result);
printf}
else {
("error");
puts}
if (power(DBL_MAX, 2.0, &result)) {
("%lf\n", result);
printf}
else {
("error");
puts}
if (power(0.0, 0.0, &result)) {
("%lf\n", result);
printf}
else {
("error");
puts}
}
実行結果:
16.000000
error
1.000000
return 0;
を削除(C言語編全体でのコードの統一)
Programming Place Plus のトップページへ
はてなブックマーク に保存 | Pocket に保存 | Facebook でシェア |
X で ポスト/フォロー | LINE で送る | noteで書く |
RSS | 管理者情報 | プライバシーポリシー |