問題① 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)
{
("%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));
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};
("%lf\n", distance2d(&p1, &p2));
printf("%lf\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};
("%lf\n", distance2d(&p1, &p2));
printf("%lf\n", distance2d(&p2, &p1));
printf}
実行結果:
5.000000
5.000000
{
の直後と、}
の直前に空白を入れない)(
の直後、)
の直前に空白を入れない)return 0;
を削除(C言語編全体でのコードの統一)新規作成。
Programming Place Plus のトップページへ
はてなブックマーク に保存 | Pocket に保存 | Facebook でシェア |
X で ポスト/フォロー | LINE で送る | noteで書く |
RSS | 管理者情報 | プライバシーポリシー |