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

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

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

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

Q&A

解決済

2回答

1395閲覧

c言語 分散の計算結果が合わないので見ていただきたいです。

Giruba

総合スコア5

C

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

0グッド

0クリップ

投稿2021/05/08 13:55

前提・実現したいこと

ある100行2列の数字が入ったファイルを使い、一列づつの合計、平均、分散、標準偏差を求めるプログラミングを考えているんですが、合計と平均値はあっているものの、分散の値が合いません。
そこで、どこが間違っているのか間違いに気づいた方に指摘していただきたいです。
■■な機能を実装中に以下のエラーメッセージが発生しました。

発生している問題・エラーメッセージ

該当のソースコード

#include <stdio.h>

int main(){
int i;
float x[101],y[101];
float sum1,sum2,ave1,ave2,bun1,bun2,hyo1,hyo2;
FILE *fp;

sum1=0.0; sum2=0.0; ave1=0.0; ave2=0.0; bun1=0.0; bun2=0.0; hyo1=0.0; hyo2=0.0; fp=fopen("input2.txt","r"); for(i=1;i<=100;i++){ fscanf(fp,"%f%f\n",&x[i],&y[i]); printf("%f,%f\n",x[i],y[i]); sum1+=x[i]; sum2+=y[i]; ave1=sum1/100.0; ave2=sum2/100.0; bun1=pow(x[i]-ave1,2.0)/100.0; bun2=pow(y[i]-ave2,2.0)/100.0; hyo1=sqrt(bun1); hyo2=sqrt(bun2); } printf("1列目の合計値は%f\n",sum1); printf("2列目の合計値は%f\n",sum2); printf("1列目の平均値は%f\n",ave1); printf("2列目の平均値は%f\n",ave2); printf("1列目の分散は%f\n",bun1); printf("2列目の分散は%f\n",bun2); printf("1列目の標準偏差は%f\n",hyo1); printf("2列目の標準偏差は%f\n",hyo2); fclose(fp); return 0;

}

試したこと

powを使わずに、二回かけて計算してみたり分散の計算を掛け算割り算足し算に分けて計算したりしました。
Googleで調べた類題の分散の計算方法と式は同じでしたので、どこが間違っているか見当がつかないです。

補足情報(FW/ツールのバージョンなど)

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

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

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

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

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

y_waiwai

2021/05/08 14:05

どういう結果になったんでしょうか。 また、それがどうなればいいというはなしですか?
Giruba

2021/05/08 15:09

求めたい分散の値は、208.70466 3342.540283 です。 しかし、計算してみるとこれよりすこし大きかったり小さかったりしてうまく計算結果が合いません。
guest

回答2

0

c

1bun1=pow(x[i]-ave1,2.0)/100.0; 2bun2=pow(y[i]-ave2,2.0)/100.0;

このようにしていますが、ave1ave2はまだ計算中の途中経過なので、全体の平均とは一致しません。

平均値を出したあとで改めて分散を求めるか、(桁落ちのリスクはありますが)先に各値の二乗和だけ計算して最後に平均の二乗×個数を引く、というような手法で行う必要があります。

投稿2021/05/08 14:08

maisumakun

総合スコア146018

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

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

ppaul

2021/05/08 14:44

分散 =二乗平均-平均の二乗 ですね。
Giruba

2021/05/09 00:15 編集

#include <stdio.h> int main(){ int i; float x[101],y[101]; float sum1,sum2,sum3,sum4,ave1,ave2,bun1,bun2,bun3,bun4,hyo1,hyo2; FILE *fp; sum1=0.0; sum2=0.0; fp=fopen("input2.txt","r"); for(i=1;i<=100;i++){ fscanf(fp,"%f%f\n",&x[i],&y[i]); printf("%f,%f\n",x[i],y[i]); sum1+=x[i]; sum2+=y[i]; } ave1=sum1/100.0; ave2=sum2/100.0; for(i=1;i<=100;i++){ bun1=pow(x[i]-ave1,2.0); bun2=pow(y[i]-ave2,2.0); sum3+=bun1; sum4+=bun2; } bun3=(sum3/100.0); bun4=(sum4/100.0); hyo1=sqrt(bun3); hyo2=sqrt(bun4); printf("1列目の合計値は%f\n",sum1); printf("2列目の合計値は%f\n",sum2); printf("1列目の平均値は%f\n",ave1); printf("2列目の平均値は%f\n",ave2); printf("1列目の分散は%f\n",bun1); printf("2列目の分散は%f\n",bun2); printf("1列目の標準偏差は%f\n",hyo1); printf("2列目の標準偏差は%f\n",hyo2); fclose(fp); return 0; } このように書き換えてみたのですが、やはり計算がありません。 まだ計算途中の場所はありますか?
guest

0

ベストアンサー

分散の計算が間違っています。

各値と平均の差の2乗和を取るなら分散は平均値が求まってからでないと求められないので
forループは(平均値算出のための)総和を求める1回と
分散を求めるための1回で計2回必要になります。

投稿2021/05/08 14:10

編集2021/05/08 14:12
ozwk

総合スコア13553

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

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

maisumakun

2021/05/08 14:13

> 分散は平均値が求まってからでないと求められないので 数式を工夫すれば、ループ1回で平均値と同時に算出することも可能です。
ozwk

2021/05/08 14:14

ということに気づいたので修正しました
Giruba

2021/05/09 01:17 編集

#include <stdio.h> int main(){ int i; float x[101],y[101]; float sum1,sum2,sum3,sum4,ave1,ave2,bun1,bun2,bun3,bun4,hyo1,hyo2; FILE *fp; sum1=0.0; sum2=0.0; fp=fopen("input2.txt","r"); for(i=1;i<=100;i++){ fscanf(fp,"%f%f\n",&x[i],&y[i]); printf("%f,%f\n",x[i],y[i]); sum1+=x[i]; sum2+=y[i]; } ave1=sum1/100.0; ave2=sum2/100.0; for(i=1;i<=100;i++){ bun1=pow(x[i]-ave1,2.0); bun2=pow(y[i]-ave2,2.0); sum3+=bun1; sum4+=bun2; } bun3=(sum3/100.0); bun4=(sum4/100.0); hyo1=sqrt(bun3); hyo2=sqrt(bun4); printf("1列目の合計値は%f\n",sum1); printf("2列目の合計値は%f\n",sum2); printf("1列目の平均値は%f\n",ave1); printf("2列目の平均値は%f\n",ave2); printf("1列目の分散は%f\n",bun3); printf("2列目の分散は%f\n",bun4); printf("1列目の標準偏差は%f\n",hyo1); printf("2列目の標準偏差は%f\n",hyo2); fclose(fp); return 0; } アドバイス通りforを二回使ってみたのですが、計算結果が合いません。 forループの使い方が間違っているのでしょうか?
ozwk

2021/05/08 22:03

bun3と4が使われてません
Giruba

2021/05/09 00:14

hyoのところに、bun3,bun4を使いました。 しかし、分散の計算が合いません。 何かほかに原因は考えられますでしょうか?
ozwk

2021/05/09 00:56

表示しているものがbun1,2のままです
Giruba

2021/05/09 01:16

ご指摘通り変更しました。 分散のyの方は求めたい答えが出せたのですが、分散のxのほうが400304413838444597248000000000000.000000となってしまい、明らかに計算結果がおかしくなってしまいます。 yの方としている計算は違わないはずなのに、何が原因かわかりません。 考えられる要因はありますでしょうか?
ozwk

2021/05/09 01:41

ソース貼ってください。
Giruba

2021/05/09 11:08

なんとかできました! 最後までアドバイスしてくださりありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問