数学関数 解答ページ | Programming Place Plus C言語編 第48章

トップページC言語編第48章

問題①

問題① 2つの浮動小数点数が、どれだけ離れているかを計算するプログラムを作成してください。


たとえば、3 と 7 の間の距離は +4 ですが、これは反対の方向から見ても(つまり、7 から 3)やはり +4 です。

3 - 7 とすると -4 が得られ、7 - 3 とすると +4 が得られます。結局、どちらからどちらを減算しても、絶対値を取れば目的の値が得られます。

元の数が負数であっても同様です。-3 と -7 だっとすると、(-3) - (-7) は +4、(-7) - (-3) なら -4 になります。絶対値を取れば、やはり 4 です。

つまり、プログラムとしては、どちらからどちらを減算しても問題なく、結果の絶対値を取れば良いということになります。

#include <math.h>
#include <stdio.h>

double distance(double p1, double p2)
{
    return fabs(p1 - p2);
}

int main(void)
{
    printf("%lf\n", distance(3, 7));
    printf("%lf\n", distance(7, 3));
    printf("%lf\n", distance(-3, -7));
    printf("%lf\n", distance(-7, -3));

    printf("%lf\n", distance(3, -7));
    printf("%lf\n", distance(7, -3));
    printf("%lf\n", distance(-3, 7));
    printf("%lf\n", distance(-7, 3));
}

実行結果:

4.000000
4.000000
4.000000
4.000000
10.000000
10.000000
10.000000
10.000000

問題②

問題② 2次元平面上にある2つの点の間の距離を計算するプログラムを作成してください。


2つの点 (p1 と p2) を、直角三角形の直角でない頂点に対応させると、距離とは、斜辺の長さのことに他なりません。

直角三角形の辺の長さは、ほかの2つの辺の長さが分かっていれば、三平方の定理(c2 = a2 + b2)を利用して求められます。

斜辺以外の辺の長さは、x方向は p1 と p2 の x座標同士で、y方向は y座標同士で計算すれば得られます。これは、問題①でやったことと同じ要領で、fabs(p1.x - p2.x) と fabs(p1.y - p2.y) をすればいいということです。

三平方の定理の等式に当てはめて計算した結果、斜辺の長さの2乗が得られるので、平方根を取れば、斜辺の長さそのものが得られます。これが2点間の距離です。

#include <assert.h>
#include <math.h>
#include <stdio.h>

struct Point2D_tag {
    double x;
    double y;
};

double distance(double p1, double p2)
{
    return fabs(p1 - p2);
}

double distance2d(const struct Point2D_tag* p1, const struct Point2D_tag* p2)
{
    assert(p1 != NULL);
    assert(p2 != NULL);

    const double x_dist = distance(p1->x, p2->x);
    const double y_dist = distance(p1->y, p2->y);

    return sqrt(x_dist * x_dist + y_dist * y_dist);
}

int main(void)
{
    struct Point2D_tag p1 = {3, 9};
    struct Point2D_tag p2 = {7, 6};

    printf("%lf\n", distance2d(&p1, &p2));
    printf("%lf\n", distance2d(&p2, &p1));
}

実行結果:

5.000000
5.000000

sqrt関数は、実引数が負数のときに定義域エラーを発生させますが(本編参照)、今回のような使い方では、必ず正の数を渡すので、エラーが発生することはありません。

三平方の定理を使って斜辺の長さを求めるために、hypot関数を使う方法もあります。こちらの方が簡単ですし、長さを2乗するときに発生するかもしれないオーバーフローを避けて計算してくれるという利点があります。

#include <assert.h>
#include <math.h>
#include <stdio.h>

struct Point2D_tag {
    double x;
    double y;
};

double distance(double p1, double p2)
{
    return fabs(p1 - p2);
}

double distance2d(const struct Point2D_tag* p1, const struct Point2D_tag* p2)
{
    assert(p1 != NULL);
    assert(p2 != NULL);

    const double x_dist = distance(p1->x, p2->x);
    const double y_dist = distance(p1->y, p2->y);
    
    return hypot(x_dist, y_dist);
}

int main(void)
{
    struct Point2D_tag p1 = {3, 9};
    struct Point2D_tag p2 = {7, 6};

    printf("%lf\n", distance2d(&p1, &p2));
    printf("%lf\n", distance2d(&p2, &p1));
}

実行結果:

5.000000
5.000000


参考リンク


更新履歴

’2018/5/25 新規作成。



第48章のメインページへ

C言語編のトップページへ

Programming Place Plus のトップページへ



はてなブックマーク に保存 Pocket に保存 Facebook でシェア
X で ポストフォロー LINE で送る noteで書く
rss1.0 取得ボタン RSS 管理者情報 プライバシーポリシー
先頭へ戻る