HSPポータル
サイトマップ お問い合わせ


HSPTV!掲示板


未解決 解決 停止 削除要請

2014
1006
あsd連立方程式について5解決


あsd

リンク

2014/10/6(Mon) 17:19:38|NO.65457

連立方程式を解くプログラムを作っています。
Cで書いていましたがandroid化できると聞いたのでHSPに移植しようと思いました。
このプログラムを実行すると
0で除算しました というエラーが出てしまいます。
本やネットで調べましたが解決策がよくわかりません。
長文すいません。

x1=0:y1=0 ; 画面左上の座標 x2=320:y2=480 ; 画面右下の座標 screen 0,x2,y2 ;ウィンドウ表示 cls 4;画面を黒で塗る dim a;~24 変数の初期化 dim b dim c dim d dim e dim f dim g dim h dim i dim j dim k dim l dim m dim x dim y dim z dim p dim q dim n color 255,0,0 :font "MS ゴシック",80,1;~27 下の括弧の表示 pos 180,330 mes"{" color 255,0,0 :font "MS ゴシック",15,1;~30 上の式の表示 pos 100,130 mes" X+ Y= " pos 75,130;~34 上の式のaの取得 objsize 30,15 a="" input a pos 135,130;~38 上の式のbの取得 objsize 30,15 b="" input b pos 190,130;~42 上の式のcの取得 objsize 30,15 c="" input c color 255,0,0 :font "MS ゴシック",15,1;~45 下の式の表示 pos 100,180 mes" X+ Y= " pos 75,180;~49 上の式のaの取得 objsize 30,15 d="" input d pos 135,180;~53 上の式のbの取得 objsize 30,15 e="" input e pos 190,180;~57 上の式のcの取得 objsize 30,15 f="" input f pos 230,225;~60 OKボタンの表示 objsize 80,30 button"OK",*main stop *main l = a h = b m = c if a<d : goto *ax :else:goto *vs;上の式と下の式の大きさを合わせるときに大きさを変える式の判断 *ax;~73 下の式が大きかったときの計算 g =d/a a*=g b*=g c*=g goto *cv *vs;~79 上の式が大きかったときの計算 g =a/d d =g*d e =g*e; f =g*f; goto *cv *cv j =b-e;~84 上の式から下の式を引く計算 k =c-f y = k/j;yを求める計算 x = (-h*y+m)/l;xを求める計算 mes"X="+x;xの表示 mes"Y="+y;yの表示



この記事に返信する


FunnyMaker

リンク

2014/10/6(Mon) 18:04:11|NO.65458

ん~...。
なんか色々おかしいですが、応急処置をするとざっとこんな感じでしょうか?
アルゴリズムのチェックまではしていませんが、

A = matrix([1,2],[4,5])
Ax = matrix([3],[6])

(※Maxima風の記述ですみません。表現しやすいので。)

でちゃんと正しい解を出してくれることだけは一応確認しました。


x1=0:y1=0 ; 画面左上の座標 x2=320:y2=480 ; 画面右下の座標 screen 0,x2,y2 ;ウィンドウ表示 cls 4;画面を黒で塗る a = 0.0 b = 0.0 c = 0.0 d = 0.0 e = 0.0 f = 0.0 g = 0.0 h = 0.0 i = 0.0 j = 0.0 k = 0.0 l = 0.0 m = 0.0 x = 0.0 y = 0.0 z = 0.0 p = 0.0 q = 0.0 n = 0.0 color 255,0,0 :font "MS ゴシック",80,1;~27 下の括弧の表示 pos 180,330 mes"{" color 255,0,0 :font "MS ゴシック",15,1;~30 上の式の表示 pos 100,130 mes" X+ Y= " pos 75,130;~34 上の式のaの取得 objsize 30,15 input a pos 135,130;~38 上の式のbの取得 objsize 30,15 input b pos 190,130;~42 上の式のcの取得 objsize 30,15 input c color 255,0,0 :font "MS ゴシック",15,1;~45 下の式の表示 pos 100,180 mes" X+ Y= " pos 75,180;~49 上の式のaの取得 objsize 30,15 input d pos 135,180;~53 上の式のbの取得 objsize 30,15 input e pos 190,180;~57 上の式のcの取得 objsize 30,15 input f pos 230,225;~60 OKボタンの表示 objsize 80,30 button"OK",*main stop *main l = a h = b m = c if a<d : goto *ax :else:goto *vs;上の式と下の式の大きさを合わせるときに大きさを変える式の判断 *ax;~73 下の式が大きかったときの計算 g =d/a a*=g b*=g c*=g goto *cv *vs;~79 上の式が大きかったときの計算 g =a/d d =g*d e =g*e; f =g*f; goto *cv *cv j =b-e;~84 上の式から下の式を引く計算 k =c-f y = k/j;yを求める計算 x = (-h*y+m)/l;xを求める計算 mes"X="+x;xの表示 mes"Y="+y;yの表示

2元連立一次方程式ですか...。

ちょいと行列の話になりますが、
A = matrix([a11,a12],[a21,a22])
x = matrix([x1],[x2])
Ax = matrix([0],[0])
と言う風に行列のアイデアを使えば、aとかbとかまどろっこしい変数を使わなくても
配列で楽に扱えます。

n元連立1次方程式まで解いてくれるようなのをつくると面白いですね。
解の存在のチェックをしてくれたり、解空間まで求めてくれると需要あるかも?



FunnyMaker

リンク

2014/10/6(Mon) 18:07:20|NO.65459

提示されたスクリプトでうまく動かない理由のヒントをいくつか挙げます。

① 計算用の変数 (a,b,...)が文字列型で初期化されていた。
② /とすべきを/と書いている箇所がある。
③ -とすべきを-としている箇所がある。

①を直すために、実数型に置き換えておきました。



男子中学生

リンク

2014/10/6(Mon) 19:02:57|NO.65461


#define ctype f(%1) strf("%%g",%1) //0.02500・・・を0.025にする x1=3.0 x2=2.0 y1=4.0 y2=1.0 a1=5.0 a2=0.0 x5=x1:y5=y1:a5=a1 cls 4 color 255,0,0 font "",50 pos 20,50 mes "{" color 255,0,0 font "",25 pos 50,50 mes ""+f(x1)+"x+"+f(y1)+"y="+f(a1) mes ""+f(x2)+"x+"+f(y2)+"y="+f(a2) p1=x1*x2 p2=p1/x1 p3=p1/x2 x1=p2*x1 y1=p2*y1 a1=p2*a1 x2=p3*x2 y2=p3*y2 a2=p3*a2 //上、下の式のx同士の最小公倍数を掛ける color 255,0,0 font "",50 pos 20,120 mes "{" font "",25 pos 50,120 mes ""+f(x1)+"x+"+f(y1)+"y="+f(a1) mes ""+f(x2)+"x+"+f(y2)+"y="+f(a2) x3=x1-x2 y3=y1-y2 a3=a1-a2 //上の式から下の式を引く boxf 20,170,200,171 mes " "+f(y3)+"y="+f(a3) y=a3/y3 //約分 mes " y="+f(y) //yもとめられた ky=y*y5 //xを求めるために、yを代入 pos 50,250 mes ""+f(x5)+"x+"+f(ky)+"="+f(a5) a5=a5+ky*-1 //移項 ky="" mes ""+f(x5)+"x="+f(a5) x=a5/x5 //約分 mes "x="+f(x) //xもとめられた pos 50,350 mes "x="+f(x)+" y="+f(y) boxf 20,375,200,376



cats

リンク

2014/10/7(Tue) 00:16:33|NO.65467

一次の方程式を解くなら線形代数が最も簡単だと思います。
ax + by = p
cx + dy = q
について A = [a b ; c d] , B = [p ; q] すると
AX = B が成り立つので X = (A^-1)B となります。
(A^-1) = (1 / detA) * t[Aの余因子行列]
ですが、t[Aの余因子行列]は(2,2)型の正方行列の公式から[d -b ; -c a]となるので、
[d -b ; -c a] * [p ; q]を計算すると解[x ; y]がでます。
3元や4元の方程式を解きたい場合はまじめに余因子行列と転置行列を計算して
逆行列を求めた後、具体的な方法は知りませんが行列を高速に計算するアルゴリズムで
積を計算してやれば同じように解がでるはずです。

/* AX = P を X = (A^-1)P に変形して考えます。 このコードでは二元1次方程式のみ解けます。 A^-1 = (1 / detA) * t[Aの余因子行列] を使えば何元でも解けるはずです。 */ // 変数初期化 x1 = 3 : y1 = 2 : a1 = 1 x2 = 7 : y2 = 5 : a2 = -1 ix1 = 0 : iy1 = 0 ix2 = 0 : iy2 = 0 Ax = 0 : Ay = 0 objsize 24, 20 // 式1 pos 16, 8 : input x1 : pos 48, 12 : mes "X +" pos 80, 8 : input y1 : pos 112, 12 : mes "Y =" pos 144, 8: input a1 // 式2 pos 16, 32 : input x2 : pos 48, 36 : mes "X +" pos 80, 32 : input y2 : pos 112, 36 : mes "Y =" pos 144, 32: input a2 objsize 80, 24 : button "計算", *label stop *label color 255, 255, 255 : boxf 0, 64, 640, 480 : color // 係数行列についてdet(行列式の値)を求める detA = double( x1 * y2 - x2 * y1 ) pos 8, 96 : mes "detA = " +detA + "\n" if detA == 0.0 : dialog "解無し、もしくは全て" : stop // 係数行列の逆行列の各要素を求める idetA = 1.0 / double(detA) ix1 = double(y2) * idetA iy1 = double(-y1) * idetA ix2 = double(-x2) * idetA iy2 = double(x1) * idetA // 逆行列を表示 mes "係数行列の逆行列 = [" + ix1 + " " + iy1 + " ; " + ix2 + " " + iy2 + " ]\n" // 係数行列の逆行列と[ a1 a2 ]の積を求める ( [2,1]型 ) Ax = double(ix1) * double(a1) + double(iy1) * double(a2) Ay = double(ix2) * double(a1) + double(iy2) * double(a2) // 表示 mes "X = " + Ax mes "Y = " + Ay stop



あsd

リンク

2014/10/7(Tue) 19:04:03|NO.65470

 皆さん本当にありがとうございます。
僕はまだ学生ですが、たくさん練習してもっとすごいプログラムを書けるようになりたいです。
 たくさんのアドバイスありがとうございました。



ONION software Copyright 1997-2025(c) All rights reserved.