ページ 1 / 1
計算プログラム
Posted: 2009年11月14日(土) 21:51
by 9mm
太陽高度の計算プログラムとそれを利用して日射量を求めるというプログラムを作りたいのですが、まだCを始めて間もないのでどういう風に作っていけばいいかわかりません。
一応太陽高度を求める式は以下のようになっています。
sin(h)=sin(a)*sin(b)+cos(a)*cos(b)*cos(c)
h:太陽高度
a:日赤緯
b:北緯
c:時角
ここでそれぞれ
c=15*(T-12)+L-135+(e/4)
T:日本標準時 (単位:時間)
L:東経 (単位:度)
e:均時差 (単位:分)
w=360*N/366
a=0.362-23.3*cos(w+6.8)-0.337*cos(2*w-11.9)-0.185*cos(3*w+35.5)
e=-0.0167+7.37*cos(w+85.6)-9.93*cos(2*w-72.3)-0.321*cos(3*w-66.3)
N:1月1日から起算した日数
ここまでが太陽高度を求める計算です。
ここから日射量を求める計算です。
I'=I*(Pの1/sin(h)乗)
I:太陽定数=1353
P:大気透過率
これが日射量を求める計算式です。
この二つを利用して問題を解くプログラムを作成するという課題です。
1.N=1の時、1日の日射量(I')を一分毎に計算せよ。
2.毎日12時の日射毎(I')を1日毎に計算せよ。
かなり専門的な分野なので分かりにくいかと思います。すいません。
あとヒントをもらったんですが、これもよくわからないので一応乗せておきます。
m[1]=31
m[2]=28
m[3]=31
・
・
・
m[12]=31
month:月 読み込み
day:日 読み込み
M=0
for(i=1,i<month,i+t){
M=M+m
}
N=M+day
さっぱりのヒントですww
分かりづらくてすいません。ぜひお願いします。
Re:計算プログラム
Posted: 2009年11月14日(土) 22:44
by 組木紙織
なんか同じ学科のようなので、
まずはヒントから。
1: 1月1日正午の北緯0度、東経135度、での太陽高度角を求めるコードを作る。
1-1:上記のプログラムを関数化する。
2: 太陽高度角90度のときの日射量を求めるプログラムを書く。
2-1:上記のプログラムを関数化する。
ここまできちんとやってみてください
Re:計算プログラム
Posted: 2009年11月15日(日) 08:59
by non
ヒントは月日を元に、1月1日からの日数を計算する考え方ですね。
閏年が考慮されていませんから、(年の入力がない)どうするのでしょうね。考慮しなくていいのかなぁ。
Re:計算プログラム
Posted: 2009年11月15日(日) 21:52
by 9mm
まだ初めて1か月もたってないのでまったく手の着けようがないのですが…
関数化というのもどういう意味か分からないんですけど…すいません。
いろんな教科書とか見たんですが書いてある意味がさっぱりわかりません。
Re:計算プログラム
Posted: 2009年11月15日(日) 23:13
by 組木紙織
初めて一か月経ってなくても、入門書を見ながら入出力と演算を扱えるぐらいだと想定していたのですが。。
1: 1月1日正午の北緯0度、東経135度、での太陽高度角を求めるコードを作る。
はできますか?
もし出来なければ、何が問題であるのかを詳しく説明してください。
/***************/
追記
1:文章の意味がわからない。
2:コードを作るとはどのようなことであるかがわからない。
3:PC上でプログラムを作るとはどのようにすればよいかがわからない。
4:一応コードは書いたことがあるが、どのようにすれば動かせるかがわからない。
5:コードは書いて動かしたことがあるが、足し算引き算の方法がわからない。
といった感じで
自分自身の今の問題点を細かく説明してください。
Re:計算プログラム
Posted: 2009年11月16日(月) 03:00
by 9mm
何度も申し訳ないです。自分としては
1:計算式をプログラムで表せない。
2:コードとは何なのか?
3:プログラミングというものにほぼ初めて触れた。
4:参考書やサイトをみてどういう文字がどういう意味を表わすのか?は少しわかりかけているが、それをどう組み合わせて課題のようなプログラムを作成すればいいか分からない。
といった感じです。個人的にパソコンもあまりつかったことがなく、参考書などを見ても専門用語ばっかでさっぱり意味がわかりません…。先生たちもろくに教えてくれず、聞いても専門用語ばかり。。。
ほんとに無知で申し訳ないですね…。
Re:計算プログラム
Posted: 2009年11月16日(月) 07:56
by 組木紙織
そのレベルだと掲示板で解決するのはなかなか難しいですね。
(答えだけなら簡単なんですが)
コード=ソースコード
=プログラムを作ることができる文字の集まり。かな。
何か文字を表示するプログラムを作ったことはありますよね。
その時に書いたものがコードです。
これがソースコードのサンプルです
#include <stdio.h>
int main(void)
{
printf("sample\n");
return 0;
}
まずは適切な入門書や入門サイトで実力をつけることが一番だと思いますが、
課題が出来るように順を追っていきましょう。
0-1:何もしないプログラムをつくる。
0-2:Hello Wordと表示するプログラムを作る。
0-3:数字を入力して表示をするプログラムを作る。
0-4:2つの数の四則演算をするプログラムを作る。
0-5:1から1000までを表示するプログラムを作る。
0-6:1から1000までを表示するプログラムを作る。(2種類)
0-7:三角関数を扱うプログラムを作る。
0-8:太陽高度角の計算式を使ったプログラムを作る。
このうちどれまでなら出来ますか?
そして最後の出来るとこのプログラムのソースコードを載せて下さい。その時は規約を見てください。
Re:計算プログラム
Posted: 2009年11月16日(月) 09:44
by もぐりん
掲示板の使い方に慣れていないのでしょうか?
同じ質問を複数の掲示板にするのは、あまりよくありません。
(マルチポストといいます。)
なるべく、1つの掲示板で済ませるようにしましょう。
http://www3.realint.com/cgi-bin/tarticl ... intc2+9744
http://bbs.wankuma.com/index.cgi?mode=al2&namber=43658
そのうち、答えるのが面倒になり質問しっぱなしになりますよ。
初心者には難しいプログラムですので、理解できるまで先生にしつこく聞きましょう。
学生として身につけるには、それが最短の方法です。
Re:計算プログラム
Posted: 2009年11月16日(月) 10:00
by 組木紙織
マルチポストはあることを考えてしないと、ここも規約違反です。
答が欲しいだけなら、そういって課題出した人にもらってください。
自力で出来る実力が欲しいなら、お手伝いするつもりです。
Re:計算プログラム
Posted: 2009年11月19日(木) 00:04
by 9mm
マルチポスト…知りませんでした…。申し訳ないです。
一応自分で計算部分のプログラムを作ったんですが、うまく動きません。
以下
// test3.cpp : コンソール アプリケーションのエントリ ポイントを定義します。
//
#include "stdafx.h"
#include "math.h"
int _tmain(int argc, _TCHAR* argv[/url])
{
float w,n,a,b,t,T,L,c,h;
n=1.0;
T=0.0;
L=131.62;
c=33.23;
w=(360*n)/366;
printf("%lf\n",w);
a=0.362-23.3*cos(w+8.8)-0.337*cos(2*w-11.9)-0.185*cos(3*w+35.5);
printf("%lf\n",a);
b=-0.0167+7.37*cos(w+85.8)-9.93*cos(2*w-72.3)-0.321*cos(3*w-66.3);
printf("%lf\n",b);
t=15*(T-12)+L-135+(b/4);
printf("%lf\n",t);
sin(h)=sin(c)*sin(a)+cos(c)*cos(a)*cos(t);
printf("%lf\n",sin(h));
return 0;
}
これではちゃんと計算できないんですが、どうすればいいんでしょうか?
Re:計算プログラム
Posted: 2009年11月19日(木) 02:10
by 組木紙織
マルチポストもそうですが、規約は見ておいてください。
コンパイラはVisual Studioですか?
コードを投稿するときは<pre></pre>で囲んでください。
上のコードだと計算がちゃんと出来ない以前にコンパイル(意味わかりますよね)出来ません。
出来るだけ、コンパイル可能な状態のコードを載せるようにしてほしいと思います。
うまくいかないときは"どのように"うまくいかないかを書いてください。
と以上が上記のコメントを読んで気になったことです。
問題は"何故うまく動かないか?"ですよね。
一番大きな問題はコンパイル出来ないということです。
>sin(h)=sin(c)*sin(a)+cos(c)*cos(a)*cos(t);
ここの部分でエラーが起きます。
理由は'='の左側が変数でないからです。
C言語の'='は数学の'='とは意味が違います。'='使い方を確認しておいてください。
たぶんコンパイルが出来ても求める結果が出てこないと思います。
以下の(1),(5)を気にして書き直してみてください。
以下はコードできになったことです。わからなければ無視してもかまいません。
1:C言語の三角関数は度数法でなく孤度法で扱ってます。
2:宣言の型は"double"でなく、"float"なのか?通常の場合はdoubleを使うことが多いです。
3:コメントは書いてほしいです。見せるためだけではなく後々の自分のためにも。
4:今回の場合は、printf("%lf")でなく、printf("%f")でいいのでは?
5:最初にあげた式と、コード中の式が少し異なっているのは問題ないことなのか?
Re:計算プログラム
Posted: 2009年11月19日(木) 16:35
by 9mm
>コンパイラはVisual Studioですか?
Visual Studioを使っています。
>コードを投稿するときは<pre></pre>で囲んでください。
よく意味がわからないんですが…どうすればいいんですか?
>上のコードだと計算がちゃんと出来ない以前にコンパイル(意味わかりますよね)出来ません。出来るだけ、コンパイル可能な状態のコードを載せるようにしてほしいと思います。
一応プログラムに入力した通りをそのままコピぺしたんですが、それじゃダメなんですかね?
>理由は'='の左側が変数でないからです。
'='の意味は右辺に左辺を代入するというものではなかったでしょうか?確か…間違ってたらすいません。
>C言語の三角関数は度数法でなく孤度法で扱ってます。
孤度法はπを使う方法ですか?どうやって未知数の部分を孤度法にすればいいんでしょうか?
自分で書きなおしてみましたが、やはり結果が上から3番目の式までしか出ませんでした…
以下
<pre>
// test3.cpp : コンソール アプリケーションのエントリ ポイントを定義します。
//
#include "stdafx.h"
#include "math.h"
int _tmain(int argc, _TCHAR* argv[/url])
{
double w,n,a,b,t,T,L,c,h;
n=1.0;
T=0.0;
L=131.62;
c=33.23;
w=(360*n)/366;
printf("%f\n",w);
a=0.362-23.3*cos(w+8.8)-0.337*cos(2*w-11.9)-0.185*cos(3*w+35.5);
printf("%f\n",a);
b=-0.0167+7.37*cos(w+85.8)-9.93*cos(2*w-72.3)-0.321*cos(3*w-66.3);
printf("%f\n",b);
t=15*(T-12)+L-135+b/4;
printf("%f\n",t);
sin(h)=sin(c)*sin(a)+cos(c)*cos(a)*cos(t);
printf("%f\n",sin(h));
return 0;
}
</pre>
↑こんな感じで囲むんですか?
Re:計算プログラム
Posted: 2009年11月19日(木) 16:55
by dic
>sin(h)=sin(c)*sin(a)+cos(c)*cos(a)*cos(t);
コンパイル通ります?
Re:計算プログラム
Posted: 2009年11月19日(木) 18:22
by non
> >コードを投稿するときは<pre></pre>で囲んでください。
> よく意味がわからないんですが…どうすればいいんですか?
規約に使い方はありますが、<>は半角です。 組木紙織さんは、説明の都合上全角で書いています。
> >理由は'='の左側が変数でないからです。
> '='の意味は右辺に左辺を代入するというものではなかったでしょうか?確か…間違ってたらすいません。
そう、代入です。従って、プログラムの場合は左辺には、変数がきます。
求めたいのがhなら
h= に式を変形してください。
>
> >C言語の三角関数は度数法でなく孤度法で扱ってます。
> 孤度法はπを使う方法ですか?どうやって未知数の部分を孤度法にすればいいんでしょうか?
180:π=deg:rad です。
変形すると
rad=3.141592/180*deg になります
Re:計算プログラム
Posted: 2009年11月20日(金) 17:57
by 9mm
>求めたいのがhなら
h= に式を変形してください。
これはどういう風にすればいいんでしょうか?先生に聞いたらそのままsin(h)の式を書いていけばできるといわれたんですが…。
>180:π=deg:rad です。
変形すると
rad=3.141592/180*deg になります
これをどういう風に組み込めばいいんですか?できれば参考プログラムみたいなのがあればいいんですが…
Re:計算プログラム
Posted: 2009年11月20日(金) 18:30
by non
sin(h)=a なら
h=asin(a) です。 asin はアークサインのこと。
cos(deg)なら ラジアンにしなくてはいけないので
cos(3.141592/180*deg)と書きましょうってこと。
Re:計算プログラム
Posted: 2009年11月20日(金) 20:22
by Jitta
http://bbs.wankuma.com/index.cgi?mode=al2&namber=43658
ほったらかしですか。こういう事をするから、「マルチスレッド禁止」といわれます。
> sin(h)=sin(a)*sin(b)+cos(a)*cos(b)*cos(c)
>
> h:太陽高度
> a:日赤緯
> b:北緯
> c:時角
>
> ここでそれぞれ
>
> c=15*(T-12)+L-135+(e/4)
>
> T:日本標準時 (単位:時間)
> L:東経 (単位:度)
> e:均時差 (単位:分)
>
> w=360*N/366
>
> a=0.362-23.3*cos(w+6.8)-0.337*cos(2*w-11.9)-0.185*cos(3*w+35.5)
>
> e=-0.0167+7.37*cos(w+85.6)-9.93*cos(2*w-72.3)-0.321*cos(3*w-66.3)
>
> N:1月1日から起算した日数
この中で、e が2回出てきています。
> c=15*(T-12)+L-135+(e/4)
> e=-0.0167+7.37*cos(w+85.6)-9.93*cos(2*w-72.3)-0.321*cos(3*w-66.3)
c を求めるための e と、三角関数で計算をしている e は、同じ物でしょうか?
> b=-0.0167+7.37*cos(w+85.8)-9.93*cos(2*w-72.3)-0.321*cos(3*w-66.3);
> printf("%lf\n",b);
> t=15*(T-12)+L-135+(b/4);
> printf("%lf\n",t);
> sin(h)=sin(c)*sin(a)+cos(c)*cos(a)*cos(t);
ここで、最初に提示された式と異なっています。最初の式、
「c=15*(T-12)+L-135+(e/4)」が、
「t=15*(T-12)+L-135+(b/4)」になっています。ここは、b でしょうか、e でしょうか。
上の式は、「1時間あたりの自転角度は15度。1分あたりの自転角度は4度。南中時を0度として、日本標準時を基準に、求める時間の南中時からずれている角度を求める」式であるとわかります。
しかし、下の式は、bがなんなのか、わかりません。これは、何を表しているのでしょう?
> I'=I*(Pの1/sin(h)乗)
>
> I:太陽定数=1353
> P:大気透過率
P の具体的な数値が提示されていません。
> L=131.62;
> c=33.23;
大分県ですね。
> 求めたいのがhなら
> h= に式を変形してください。
変形する必要はありません。最終的な I' は、「I'=I*(P^(1/sin(h))) 」です。
sin(h) そのものを S とすると、「I' = I * (P^(1/S))」です。
Re:計算プログラム
Posted: 2009年11月20日(金) 20:40
by 9mm
アドバイスのおかげで太陽高度のhまでは求められたと思います。
ありがとうございます。
次に日射量を求める計算式をプログラムの中に書き込んだんですが、結果の中に
<1.#INFOO>
というものが出てきました。これはどういうことなんでしょうか?
以下
// test3.cpp : コンソール アプリケーションのエントリ ポイントを定義します。
//
#include "stdafx.h"
#include "math.h"
int _tmain(int argc, _TCHAR* argv[/url])
{
double w,n,a,b,t,T,L,c,h,I,i,P;
n=1.0;
T=0.0;
L=131.62;
c=33.23;
i=1353;
P=0,69;
w=(360*n)/366;
printf("%f\n",w);
a=0.362-23.3*cos((3.141592/180)*(w+8.8))-0.337*cos((3.141592/180)*(2*w-11.9))-0.185*cos((3.141592/180)*(3*w+35.5));
printf("%f\n",a);
b=-0.0167+7.37*cos((3.141592/180)*(w+85.8))-9.93*cos((3.141592/180)*(2*w-72.3))-0.321*cos((3.141592/180)*(3*w-66.3));
printf("%f\n",b);
t=15*(T-12)+L-135+b/4;
printf("%f\n",t);
h=asin(sin((3.141592/180)*c)*sin((3.141592/180)*a)+cos((3.141592/180)*c)*cos((3.141592/180)*a)*cos((3.141592/180)*t));
printf("%f\n",h);
I=i*(pow(P,(1/sin((3.141592/180)*h))));
printf("%f\n",I);
return 0;
}
Re:計算プログラム
Posted: 2009年11月20日(金) 23:09
by non
まず、マルチポストを謝って回ることでしょう。
Re:計算プログラム
Posted: 2009年11月21日(土) 00:26
by 9mm
>「c=15*(T-12)+L-135+(e/4)」が、
「t=15*(T-12)+L-135+(b/4)」になっています。ここは、b でしょうか、e でしょうか。
上の式は、「1時間あたりの自転角度は15度。1分あたりの自転角度は4度。南中時を0度として、日本標準時を基準に、求める時間の南中時からずれている角度を求める」式であるとわかります。
しかし、下の式は、bがなんなのか、わかりません。これは、何を表しているのでしょう?
b=eです。特に文字を決めてやっていなかったのでなんかごちゃごちゃになってしまいました…。
>P の具体的な数値が提示されていません。
Pは元々与えられていません。
>まず、マルチポストを謝って回ることでしょう。
放置してそのままでしたね…。助言ありがとうございます。
Re:計算プログラム
Posted: 2009年11月21日(土) 01:06
by 組木紙織
>アドバイスのおかげで太陽高度のhまでは求められたと思います。
太陽高度角正しく求められていないはずです。
チェックをしてください。
日本付近で真夜中に太陽高度角が-1度そこらなんてありえないです。
aの日赤緯の計算のところですが
最後のコード中の式
a=0.362-23.3*cos(w+8.8)-0.337*cos(2*w-11.9)-0.185*cos(3*w+35.5)
最初に提示した式
a=0.362-23.3*cos(w+6.8)-0.337*cos(2*w-11.9)-0.185*cos(3*w+35.5)
のどちらが正しいのですか?
Re:計算プログラム
Posted: 2009年11月21日(土) 01:20
by 9mm
>太陽高度角正しく求められていないはずです。
確かに。数値が出たので安心してました。どこが違うんですかね?
aについては最後に示した式が正しいです。
ほかの部分はあってるんですかね?
Re:計算プログラム
Posted: 2009年11月21日(土) 01:29
by 組木紙織
>ほかの部分はあってるんですかね?
自分で確認してみてください。
自分で電卓を使って一つづつ計算した結果と、プログラムの結果を照らし合わせてみてください。
あ。一つ聞き忘れていました。
太陽定数の単位はどのような単位ですか?
#一応私のほうでプログラムは作っているので、それと照らし合わせることぐらいなら出来ます。
Re:計算プログラム
Posted: 2009年11月21日(土) 01:51
by 9mm
一応電卓で全部計算しました。
最後の太陽高度角のhはsin(h)のままで計算したら正確な数値っぽいのが出ました。
以下
S=sin((3.141592/180)*c)*sin((3.141592/180)*a)+cos((3.141592/180)*c)*cos((3.141592/180)*a)*cos((3.141592/180)*t);
printf("%f\n",S);
後はこれを利用した日射量だけです。
太陽定数はω/㎡というものです。
Re:計算プログラム
Posted: 2009年11月21日(土) 02:22
by 組木紙織
日射量の計算式は
>I'=I*(Pの1/sin(h)乗)
これですね。
この式だと太陽が真上にあるときが一番日射量が少なくなるので変な感じなのですが、それは置いておきます。
もう出来ると思うのでやってください。
>太陽定数はω/㎡というものです。
ω(オメガ)でなくて、W(ワット)ですよね。
ということはSI単位系なので時間の単位は秒。
課題の一つ目は一日の日射量なので、時間の単位に気をつけて考えてみてください。
Re:計算プログラム
Posted: 2009年11月21日(土) 02:47
by 9mm
日射量の式をプログラムで表わすと
I=i*(pow(P,(1/S)));
という式で大丈夫ですよね?
Re:計算プログラム
Posted: 2009年11月21日(土) 08:48
by 組木紙織
>I=i*(pow(P,(1/S)));
>という式で大丈夫ですよね?
プログラム中の式の問題ではなく、一番最初に提示された式のことです。
その式では太陽高度角が90度のときに最小となり、太陽高度角が0度のときに最大(無限大)となるように
なっており、私が想定している日射量の定義と異なるので、どうなのかなと思っているだけです。
Re:計算プログラム
Posted: 2009年11月22日(日) 15:58
by Jitta
> その式では太陽高度角が90度のときに最小となり、太陽高度角が0度のときに最大(無限大)となる
sin 関数のグラフを書けばわかるんですけどね。
sin(0度) = 0 → 「<1.#INFOO>」の理由
sin(90度) = 1
南中時→太陽高度が日本ではあり得ないが90度→sin(90度)=1
I' = I * pow(P, 1 / 1) → I * P
太陽高度が45度→sin(45度)=0.5
I' = I * pow(P, 1 / 0.5) → I * pow(P, 2) → I * P * P
「日射量 計算」で、検索した
http://www.es.ris.ac.jp/~nakagawa/met_cal/solar.html
http://sakura-tyo.com/haysan/autoac-71.htm
P は、月によって変わるらしい。
http://www.pu-kumamoto.ac.jp/~m-tsuji/k ... yu0201.pdf
この PDF ファイル5ページ目に「ブーゲの式」として出てきている式のようですね。
Re:計算プログラム
Posted: 2009年11月24日(火) 19:17
by 9mm
自分でTの値を変えて確かめたのですが、日射量の結果が0.0000といったものになってしまいます。
なぜでしょうか?
Re:計算プログラム
Posted: 2009年11月24日(火) 22:09
by Jitta
> 自分でTの値を変えて確かめたのですが、日射量の結果が0.0000といったものになってしまいます。
ほかの条件は?あるいは、T が何の時にですか?
今の状態では、「コーディングミスでしょう」としか、言いようがありません。
> >P の具体的な数値が提示されていません。
>
> Pは元々与えられていません。
与えられていないなら、計算できません。P という不明な数として残すしかありません。
Re:計算プログラム
Posted: 2009年11月25日(水) 02:09
by 組木紙織
>Jittaさん
PとIを入れ違えてて、勘違いしてしまいました。
9mmさんにも迷惑をかけたようですみませんでした。
>自分でTの値を変えて確かめたのですが、日射量の結果が0.0000といったものになってしまいます。
欲しい結果がその値なら問題ないと思います。
夜の間の日射量は定義できないとするか、0とするかだと思います。
なので夜の間の時間と考えているのなら0で問題ないかと思います。
#今までの範囲でコードを組んでみました。
#エラー処理は一切していません。
Re:計算プログラム
Posted: 2009年11月25日(水) 12:59
by 9mm
組木紙織さん、ありがとうございます。
次の段階としてこれをループさせて1日の日射量の計算を行いたいんですが、ループの仕組みがいまいちわかりません…。
最初に提示していた
1.N=1の時、1日の日射量(I)を一分毎に計算せよ。
2.毎日12時の日射毎(I)を1日毎に計算せよ。
という条件をループでどういう風に表現するのでしょうか?
先生からは今作っている計算式のプログラムの前にすればいいということだったんですが…
何度も質問ばっかで申し訳ないです。
Re:計算プログラム
Posted: 2009年11月25日(水) 22:31
by Jitta
大きいので端折りますが、課題1は、こんな結果でよろしいでしょうか?
N = 1 1/ 1(11:51), Insolation = 888.910
N = 1 1/ 1(11:52), Insolation = 889.027
N = 1 1/ 1(11:53), Insolation = 889.134
N = 1 1/ 1(11:54), Insolation = 889.231
N = 1 1/ 1(11:55), Insolation = 889.318
N = 1 1/ 1(11:56), Insolation = 889.394
N = 1 1/ 1(11:57), Insolation = 889.460
N = 1 1/ 1(11:58), Insolation = 889.517
N = 1 1/ 1(11:59), Insolation = 889.563
N = 1 1/ 1(12:00), Insolation = 889.599
N = 1 1/ 1(12:01), Insolation = 889.625
N = 1 1/ 1(12:02), Insolation = 889.641
N = 1 1/ 1(12:03), Insolation = 889.647
N = 1 1/ 1(12:04), Insolation = 889.642
N = 1 1/ 1(12:05), Insolation = 889.628
N = 1 1/ 1(12:06), Insolation = 889.603
N = 1 1/ 1(12:07), Insolation = 889.569
N = 1 1/ 1(12:08), Insolation = 889.524
N = 1 1/ 1(12:09), Insolation = 889.469
N = 1 1/ 1(12:10), Insolation = 889.404
なお、場所は明石市役所(東経 134度59分, 北緯 34度28分)、
P は先の「日射計算詳細」ページより、1月の0.8を使用しました。
void PrintResult(const struct tm when, double insolation) {
// tm 構造体を使えば、m[1]=31のヒントは要らない
// でも、それを使うように作らないと、他の人に作ってもらったことがばれる
_tprintf(_T("N = %d %2d/%2d(%02d:%02d), Insolation = %8.3f\n")
, when.tm_yday + 1, when.tm_mon + 1, when.tm_mday
, when.tm_hour, when.tm_min, insolation);
}
void Exercise1(const double NorthLatitude, const double EastLongitude)
{
struct tm when, *dummy;
time_t now;
time(&now);
dummy = localtime(&now);
memcpy(&when, dummy, sizeof(struct tm));
when.tm_mon = 0;
when.tm_mday = 1;
when.tm_hour = 0;
when.tm_min = 0;
// メインはこのループだけ
for (int i = 0; i < 60 * 24; ++i) {
(void) mktime(&when);
double insolation = CalcInsolation(NorthLatitude, EastLongitude, when);
PrintResult(when, insolation);
when.tm_min += 1;
}
}
Re:計算プログラム
Posted: 2009年11月25日(水) 22:41
by 組木紙織
>次の段階としてこれをループさせて1日の日射量の計算を行いたいんですが、ループの仕組みがいまいちわかりません…。
forやwhileやdoでループを作る方法がわからないということですか?
その場合は入門書に使い方があるはずなのでそれで使い方を覚えてください。
日射量の計算でループの回し方がわからない場合は、日射量の計算に必要な変数をじっくり見てください。
1分おきに計算する場合、変化する変数と変化しない変数があります。
Re:計算プログラム
Posted: 2009年11月26日(木) 12:41
by 9mm
>forやwhileやdoでループを作る方法がわからないということですか?
for文はわかります。ただ、その中身をどういう風に書き込めばいいかがわかりません。
>日射量の計算でループの回し方がわからない場合は、日射量の計算に必要な変数をじっくり見てください。
1分おきに計算する場合、変化する変数と変化しない変数があります。
1.の場合変化するのはT
2.の場合変化するのはN
だと思うんのですが・・・
Re:計算プログラム
Posted: 2009年11月26日(木) 13:47
by バグ
>>for文はわかります。ただ、その中身をどういう風に書き込めばいいかがわかりません。
いや、こういうのを『分かっていない』というんでは…
Re:計算プログラム
Posted: 2009年11月26日(木) 14:01
by 組木紙織
Jittaさんのコード見れば殆どそのまま答が乗っているとおもいます。
1から100迄順番に表示するプログラムとその和を表示するプログラムを書いてください
Re:計算プログラム
Posted: 2009年11月26日(木) 14:44
by 9mm
>for (int i = 0; i < 60 * 24; ++i)
この部分はわかります。その後の
(void) mktime(&when);
double insolation = CalcInsolation(NorthLatitude, EastLongitude, when);
PrintResult(when, insolation);
when.tm_min += 1;
の部分がよくわからないんですが・・・
Re:計算プログラム
Posted: 2009年11月26日(木) 19:59
by 組木紙織
その良く分からない部分は置いといて、(動作を説明しても意味が無いと思いますが、何をしたいかはわかりますよね。)
今までの流れと、ループをそこまで分かっていて何で出来ないかが分かりません。
今までに自分が書いたコードと、わたしがあげたコードきちんと理解していますか?
遠回りに思うかもしれませんが、先程のわたしがやってほしいと書いた事をやって貰えませんか?
Re:計算プログラム
Posted: 2009年11月26日(木) 20:23
by たいちう
Re:計算プログラム
Posted: 2009年11月26日(木) 22:38
by Jitta
わからないから、どうしました?
私のコードは、組木紙織さんのコードを見て、課題1に相当する部分だけを持ってきました。
私は CalcInsolation 関数の中で、組木紙織さんのコードでは calcSunAngleSin に相当する関数を呼んでいます。
// イメージ
main() {
Exercise1();
}
void Exercise1() {
日射量 = CalcInsolation();
printf(日射量);
}
void CalcInsolation() {
太陽高度の正弦 = calcSunAngleSin();
return 日射量を計算;
}
ですから、下のコードから、 T, L, b, N に相当する物を抜き出せば良いでしょう。
for (int i = 0; i < 60 * 24; ++i) {
(void) mktime(&when);
double insolation = CalcInsolation(NorthLatitude, EastLongitude, when);
PrintResult(when, insolation);
when.tm_min += 1;
}
この中で N に相当するのは、「when.tm_yday」です。tm_yday は、mktime の中で、tm_year, tm_mon, tm_mday から計算されます。
T に相当するのは、「when.tm_hour」と「when.tm_min」から計算します。
Re:計算プログラム
Posted: 2009年11月27日(金) 01:14
by 9mm
ここの書き込みと先生からのヒントを使って自分でそれらしいプログラムを作ってみました。値はおかしいことになってます…。Tの単位の問題だとは思うんですが…
#include "stdafx.h"
#include "math.h"
int _tmain(int argc, _TCHAR* argv[/url])
{
FILE *pf=fopen("test3.txt","w");
for(int T=0;T<=24;T+(1/60))
{
double w,n,a,b,t,L,c,S,I,d,P;
n=1.0;
L=131.62;
c=33.23;
d=1353;
P=0.7;
w=(360.0*n)/366.0;
//printf("%f\n",w);
a=0.362-23.3*cos((3.141592/180.0)*(w+8.8))-0.337*cos((3.141592/180.0)*(2.0*w-11.9))-0.185*cos((3.141592/180.0)*(3.0*w+35.5));
//printf("%f\n",a);
b=-0.0167+7.37*cos((3.141592/180.0)*(w+85.8))-9.93*cos((3.141592/180.0)*(2.0*w-72.3))-0.321*cos((3.141592/180.0)*(3.0*w-66.3));
//printf("%f\n",b);
t=15.0*(T-12.0)+L-135.0+b/4;
//printf("%f\n",t);
S=sin((3.141592/180.0)*c)*sin((3.141592/180.0)*a)+cos((3.141592/180.0)*c)*cos((3.141592/180.0)*a)*cos((3.141592/180.0)*t);
//printf("%f\n",S);
I=d*(pow(P,(1/S)));
fprintf(pf,"%f\n",I);
}
fclose(pf);
return 0;
}
tm構造体がいまいちよく分かんないですが、やはりこれを使わないとできないんでしょうか?
Re:計算プログラム
Posted: 2009年11月27日(金) 01:25
by 組木紙織
Jittaさんが
>// tm 構造体を使えば、m[1]=31のヒントは要らない
と書いてあります。
>ここの書き込みと先生からのヒントを使って自分でそれらしいプログラムを作ってみました。値はおかしいことになってます…。Tの単位の問題だとは思うんですが…
ループごとのTの値を確認してみましたか?
Tは整数型なので、整数以外の値をとれません。
整数以外が扱いたいのなら別の型を使いましょう。
Re:計算プログラム
Posted: 2009年11月27日(金) 23:41
by Jitta
> 値はおかしいことになってます…。
どの様な値を期待して、実際にはどの様な値が出力されるのでしょうか?
「おかしい」という言葉だけでなく、「どうなっているから」「おかしいと判断したのか」、判断の根拠を示して下さい。
判断の根拠があることによって、何を間違えているのか、判断が出来るようになります。
とりあえず、「printf("%f\n", (1/60));」をしてみて下さい。"0.000000" になりませんか?
「整数 / 整数」は、「整数」です。答えを実数にするには、除数、被除数のどちらかを実数にします。
1 / 60 → 整数
1 / 60. または 1. / 60 または 1. / 60. → 実数
以下、余談
> //printf("%f\n",w);
これは、こうしてみましょう。→ fprintf(pf, "w=%f\t", w);
1行に並んで入ります。
> for(int T=0;T<=24;T+(1/60))
「T<=24」なので、24時、すなわち0時が2回カウントされます。
また、実数の演算では誤差が蓄積します。「for (int wT = 0; wT < 24 * 60; ++wT)」としておき、ループ内で「double T = wT / 60.;」とした方が、誤差が少なくなるでしょう。
# w は work の意です。
課題2の方も、コードを出しておきます。
void Exercise2(const double NorthLatitude, const double EastLongitude)
{
struct tm when;
time_t now = time(0);
memcpy(&when, localtime(&now), sizeof(struct tm));
when.tm_mon = 0;
when.tm_mday = 1;
when.tm_hour = 12;
when.tm_min = 0;
(void) mktime(&when);
do {
double insolation = CalcInsolation(NorthLatitude, EastLongitude, when);
PrintResult(when, insolation);
when.tm_mday += 1;
(void) mktime(&when);
} while(when.tm_yday > 0);
}
太陽高度や日射量を計算する部分を関数として切り出しておくことで、再利用できるようにしています。
mktime について、種明かしをしておきます。
計算に必要なのは「1月1日からの積算日」です。これを計算するためには、各月が何日まであるかを意識しなければなりません。
ところが、実際には、1~365まで順番に回すだけなので、「m[1]=31」のヒントは必要ないのです。
しかし、せっかくくれたヒントなので、何かに使いましょう。…と考えたところ、とりあえず、「x月x日(N日目)」と表示することを思いつきました。
tm 構造体の tm_mon と tm_mday で、月日が出ます。tm_yday は、1月1日からの積算日が入っています。でも、tm_mon = 0; tm_mday = 2; としたからといって、tm_yday が 1 になったりしません。いつ計算されるのでしょう?その計算をするのが、mktime です。
この関数は、1970年1月1日0時0分0秒からの経過秒数である、システム時間に変換するために使います。システム時間に変換するときに「1月33日」などを「2月2日」などに直してくれるんですね。その為に、使っています。
また、mktime をしないと tm_yday が変わらないので、do-while 文を使いました。
Re:計算プログラム
Posted: 2009年11月28日(土) 03:41
by 9mm
なんとかプログラムが完成しました。
結局tm構造体は使いませんでしたが…
協力してくださった方々ありがとうございました。