問題① 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)
{
( "%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) );
printf}
実行結果:
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)
{
( p1 != NULL );
assert( p2 != NULL );
assert
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 };
( "%f\n", distance2d( &p1, &p2 ) );
printf( "%f\n", distance2d( &p2, &p1 ) );
printf}
実行結果:
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)
{
( p1 != NULL );
assert( p2 != NULL );
assert
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 };
( "%f\n", distance2d( &p1, &p2 ) );
printf( "%f\n", distance2d( &p2, &p1 ) );
printf}
実行結果:
5.000000
5.000000
return 0;
を削除(C言語編全体でのコードの統一)’2018/5/25 新規作成。
Programming Place Plus のトップページへ