質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.35%
C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

Q&A

解決済

2回答

2021閲覧

線形補間の区間計算 対数で割る理由を知りたいです。

siusus

総合スコア25

C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

0グッド

0クリップ

投稿2021/05/07 10:44

線形補間を行うサンプルコードの中にわからない部分があります。
補間する区間を算出する関数内で既知点の総数を対数で割る処理をしているのですが、
その理由がよくわかりません。

もしかしてピボット的な位置を探しているのかと思いましたが、いまいち確信を得られませんでした。

もしかしたらすごく初歩的な内容を質問しているのかもしれませんが、
ご教授いただけないでしょうか? よろしくお願いします。

参考にさせて頂いたコードです

int Sagasu(double xx[], double x, int n) /* 該当区間を探す */ { int i, l, r, m, kaisuu; l = 0; r = n;   //この部分です。 kaisuu = (int)(log(n)/log(2)+1); for (i=1; i<=kaisuu; i++){ m = (l+r)/2; if (xx[m] <= x) l = m; else r = m; if (xx[l+1] > x) break; } return l; } double Hokan(double xx[], double yy[], double x, int k) /* 線形補間 */ { int k1; k1 = k+1; return yy[k]+(x-xx[k])*(yy[k1]-yy[k])/(xx[k1]-xx[k]); } int Datain(double xx[], double yy[]) /* テストデータ作成 y = sin(x) (x=0,10,...,360) */ { int i, n, deg; double rad; n = 36; for (i=0; i<=n; i++) { deg = 10*i; rad = 3.14159265*deg/180.0; xx[i] = deg; yy[i] = sin(rad); } return n; } /* ------------------ Main ------------------ */ int main() { int i, k, n; double x, y, xx[ND+1], yy[ND+1]; char s[135]; n = Datain(xx, yy); for (i=1; i<=4; i++) { printf(" x= "); gets(s); sscanf(s,"%lf",&x); k = Sagasu(xx, x, n); y = Hokan(xx, yy, x, k); printf(" y= %e\n", y); } return 0; } /* -- 実行例:戸川隼人「数値計算」岩波書店 p.148 プログラム7.1 -- */ /* Z:\src\C>Hokan x= 45 y= 7.044160e-01 x= 135 y= 7.044160e-01 x= 225 y= -7.044160e-01 x= 315 y= -7.044160e-01 */

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

for (i=1; i<=kaisuu; i++){ m = (l+r)/2; if (xx[m] <= x) l = m; else r = m; if (xx[l+1] > x) break; }

このloopを一回まわるたびに lとr間の距離が1/2になるから、
lとrを十分近づける(収束する)ためにloopを回る回数は (2底での)nの対数、すなわちlog(n)/log(2)。

投稿2021/05/07 11:16

編集2021/05/07 11:18
episteme

総合スコア16612

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

siusus

2021/05/07 12:27

回答ありがとうございます。 恥ずかしい話なのですが、私には高校数学的な素養がほとんどありません・・。 反復法?で解を求めようとしているのはなんとなくわかるのですが・・。 高校数学からやり直した方がいいとは思うのですが、 収束条件(?)とかの分野を勉強するのに適した検索ワードだったり、WEBページとかがあったら教えていただけないでしょうか?厚かましいお願いかもしれませんが、よろしくお願いします。
episteme

2021/05/07 13:40

高校数学からやり直すなら教科書を買い求めればよいのでは。
siusus

2021/05/07 14:12

厚かましいお願いをしてしまい、すみませんでした。 地道に勉強し直します。 ありがとうございました。
guest

0

自己解決

関数内で1/2する処理を繰り返しているので、
逆に2を何乗すればnになるかを求めれば、ループの回数を決定できる。

log2 n = X

常用対数に底を変換すると

log2 n = (log10 n) / (log10 2)

ありがとうございました。

投稿2021/05/07 15:19

編集2021/05/07 15:24
siusus

総合スコア25

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

episteme

2021/05/07 23:07

僕の回答とドコが違うんですか?
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.35%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問