先頭へ戻る

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

Programming Place Plus トップページ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( "%f\n", distance( 3,  7) );
    printf( "%f\n", distance( 7,  3) );
    printf( "%f\n", distance(-3, -7) );
    printf( "%f\n", distance(-7, -3) );

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

    return 0;
}

実行結果:

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( "%f\n", distance2d( &p1, &p2 ) );
    printf( "%f\n", distance2d( &p2, &p1 ) );

    return 0;
}

実行結果:

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( "%f\n", distance2d( &p1, &p2 ) );
    printf( "%f\n", distance2d( &p2, &p1 ) );

    return 0;
}

実行結果:

5.000000
5.000000


参考リンク


更新履歴

’2018/5/25 新規作成。



第48章のメインページへ

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

Programming Place Plus のトップページへ



はてなブックマーク に保存 Pocket に保存 Facebook でシェア
Twitter でツイート Twitter をフォロー LINE で送る
rss1.0 取得ボタン RSS 管理者情報 プライバシーポリシー