• 締切済み

分数の分母ゼロ問題

分数の計算で分母がゼロになると当然発散するわけですが、その回避の方法として以下のようなものを考えています。 x=1.0 y=0.0 a=x/y ! a=∞ ゼロ割計算が一旦発生する b=y/x ! b=0.0 if(y.eq.0.) then c=a ! しかしここでaを採用しないのでプログラムには関係なし。 else c=b ! こちらが選択される。 endif というようなものです。一旦ゼロ割が生じるけれどもそれを採用しないのでトラブル回避という格好です。このような方法は問題ないと考えられるでしょうか。 もちろん、このような簡単なプログラムではありません。複雑なアルゴリズムの中の1つの局面でこのような処理をするということです。それとも絶対このような処理は行うべきではないのでしょうか。 実験すべきかと思いますが、本当の方は複雑なので実験結果があてはまるかどうかも分からないものですので。 よろしくお願いします。

みんなの回答

  • notnot
  • ベストアンサー率47% (4854/10269)
回答No.6

#3です。 >このプログラムではゼロ割しても後の処理でその問題を回避する処置がなされるため体勢に影響はないという解釈が成り立ちます。 そのような(ゼロで割った時点でエラーが発生しないが、その結果を格納した変数を参照した時点でエラーになる)言語は今のところ実在しないでしょうね。わざとそういう言語を作れば作れますが。 実在する言語では、 ケース1: ゼロで割った時点でエラーになり、プログラムが異常終了する。異常終了を回避できない ケース2: ゼロで割った時点でエラーになり、割り込みが発生して、あらかじめ指定した処理が動く。特に処理を指定しないとプログラムが異常終了する ケース3: 演算結果として無限大相当の値を取り、エラーにならず処理続行 のいずれかです。ほとんどの実用言語はケース2だと思います。 ケース3の例としてはRubyですね。Rubyのfloat型は、通常の実数値(Cのdouble)の他にInfinty,-Infinity,NaN(=Not a Number=非数=0.0/0.0) の値も取れ、a=1.0/0.0 だと、a には Infinity が入ります。他にも数学関係の言語でも無限大を扱えると思いますよ。 したがって、 >どんな言語、どんな処理系でもこれが生じたらそのシステムは異常終了するのである は間違っています。

全文を見る
すると、全ての回答が全文表示されます。
  • Tacosan
  • ベストアンサー率23% (3656/15482)
回答No.5

「割り算の前にチェックする」のに比べて「明確なメリット」が見えないんですけど....

skmsk19410
質問者

お礼

回答有り難うございます。 私も同感です。ゼロ割問題のフォローが計算の後だったら絶対にダメなのでしょうか。私の希望はこのアルゴリズムの完全否定です。処理系や言語にかかわらず、可能性としての否定ではなく、完全否定です。

全文を見る
すると、全ての回答が全文表示されます。
  • ultraCS
  • ベストアンサー率44% (3956/8947)
回答No.4

その考え方だと、分子も0の時には通用しないとおもいますがね。 除数と被除数は両方調べる必要がありますし、実数の除算の場合、アンダーフローやオーバーフローまで含めて考えないと意味がありません。

全文を見る
すると、全ての回答が全文表示されます。
  • notnot
  • ベストアンサー率47% (4854/10269)
回答No.3

数学の話じゃなくて、プログラミングの話なら、実数のゼロ除算でどうなるかは言語によって違いますので、特定言語に限定して話さないと意味がないです。 ・例外が発生。例外処理を記述できる ・例外が発生。例外処理を記述できない ・結果が浮動小数点の無限大になり、処理続行 などなど 例外が発生するケースでは、a=x/y の時点で発生するので、その後のif文の実行がどうなるかは関係ないです。

skmsk19410
質問者

お礼

回答、有り難うございます。 ご指摘の内容はコンパイラ、処理系、言語など諸々の条件によっていろいろ変わるということかと思います。 このプログラムではゼロ割しても後の処理でその問題を回避する処置がなされるため体勢に影響はないという解釈が成り立ちます。ゼロ割した変数の内容をその後参照しないからですね。コンパイラがそのように判断するというようなことではないかと思います。 一方、その逆の解釈、すなわち、ゼロ割が生じるようなプログラムはそれがどのような局面でさえ、絶対に動作しない、どんな言語、どんな処理系でもこれが生じたらそのシステムは異常終了するのである、というものです。この場合、このアルゴリズムは何が何でも排除しなければならないわけです。 数千行程度のプログラムのバグフィックスをおこなっており、最初の質問に示したような趣旨のアルゴリズムを見つけました。この箇所こそその元凶であると特定したかったのですが、必ずしもそういうことではないということのようですね。もちろん、私がこのアルゴリズムを積極的に採用したいと思っている訳ではありません。私が期待した回答は後者、すなわち絶対回避せよ、なのです。

全文を見る
すると、全ての回答が全文表示されます。
回答No.2

前出の回答のように除数の0チェックをするのが定石です。 また、被除数、除数が整数の場合は単純な0チェックで良いですが 浮動小数点の場合は、除数の範囲チェックをする方が望ましいです。 範囲の大きさは、プログラムの仕様とか 想定される商の数値から妥当な範囲を決めるしかないでしょう

全文を見る
すると、全ての回答が全文表示されます。
  • buriburi3
  • ベストアンサー率44% (353/792)
回答No.1

どんな処理系を想定しているのか不明ですが、 大抵の処理系では0除算を実行すると除算例外またはオーバーフロー例外が発生して処理の継続が出来なくなります。 0除算は実行自体を回避すべきで除算実行前に分母の値をテストするのが普通です。

全文を見る
すると、全ての回答が全文表示されます。

関連するQ&A

  • 初期条件を代入すると分母が0になる初期値問題

    2階線形常微分方程式 (x^2 y')' = -x^2 を解くと、両辺を x で積分して x^2 y' = -x^3/3 + C 両辺を x^2 で割って y' = -x/3 + C/x^2 ... (b) 両辺を x で積分して y = -x^2/6 - C/x + D ... (a) となります。 ここで初期条件 y(0) = 1, y'(0) = 0 だと y = -x^2/6 + 1 になるらしいのですが、(a) で y(0) = 1 とおいて D について解こうと思っても、 y(0) = -C/0 + D = 1 と分母が0になってしまい計算できません。 (b) y' = -x/3 + C/x^2 の場合も同様で、 y'(0) = C/0 = 0 となってしまいます。 このような場合はどうやって積分定数 C, D を求めればよいのでしょうか? 解き方が間違っていますか? ご教示ください。よろしくお願いします。

  • BASIC言語の問題(初心者)

    こんばんは(>_<) 学校からの課題で非常に困っています!!!! BASIC言語の仕組みは読めても、どうしても組み立てが出来ないのです。。。 *1* 2の平方根を出力しなさい(二分法による平方根の計算) ただしδ=0.0001とする *2* 2の平方根を出力しなさい(ニュートン・ラプソン法による平方根の計算) ただしδ=0.0001とする ヒントとして、それぞれのアルゴリズム(?)があるので紹介します(>_<) *1*(xの平方根を精度δで求める) a←0 b←x while b-a < δ do c←(a+b)/2 if C*C > x then b←c else a←c endif done return a *2*(xの平方根を精度δで求める) y←x while │x-y*y│ < 2yδ do y←(y*y+x)/2y done return y 自分は文系で、パソコンの知識まったくないので、 どうかお助け下さいo(;△;)o涙

  • 分数の足し算をさせるプログラムが分かりません。どなたか分かりませんか?

    分数の足し算をさせるプログラムが分かりません。 C言語の問題で分数の足し算までは一応できるんですが、答えがでたときに整数で出すやり方と約分して表す方法が分かりません。 どなたか知恵を貸してくれませんか? ユーザから4つの整数を入力し、はじめに入力された2個の整数と後に入力された2個の整数を分数と考え、その分数の和を表示するプログラムを作成せよ。 例えば、「3」「4」「5」「6」と入力されたときは、3/4 + 5/6を計算する。 そのプログラム内では分数の和を計算する関数を作成する。 さらに、 約分を行う関数を 再帰呼び出しを利用して作成する。 void yakubun(int *a1, int *a2) 例えば、以下の場合1/2と表示される。 int i=10,j=20; yakubun(&i,&j); printf(“%d / %d”, i, j); ちなみにここまでできました↓ #include<stdio.h> void bunsu_tasizan(int a1,int a2,int b1,int b2, int *c1,int *c2 ) { *c1=(a1*b2)+(b1*a2); *c2=(a2*b2); } int main() { int x1,x2,y1,y2,z1,z2; printf("整数を入力してください"); scanf("%d",&x1); scanf("%d",&x2); scanf("%d",&y1); scanf("%d",&y2); if(x2==0||y2==0||x2==0&&y2==0) printf("0以外を入力してください"); else{ bunsu_tasizan(x1,x2,y1,y2,&z1,&z2); printf("%d/%d",z1,z2);} return (0); }

  • 中学校で習う比の問題で分からないところがあります。

    (X-2Y):(3X-4Y)=5:1のときX:Yを求めなさい。との問題なのですが、この場合は比の性質「A:B=C:Dのとき、AD=BC」で解けるのでしょうか。 それとも「A:B=C:DのときAC=BD」又「A:B=C:DのときBC:AD」で解くのでしょうか?どれで解けばよいでしょうか? 一応手元に回答はあるのですが、答えのみなのであまり詳しく載っていません。 回答はX:Y=9:7です。 念のため自分で計算したのですが、数字が逆になってしまいます。 ※※A※※※B※※※C※D※※ (X-2Y):(3X-4Y)=5:1 ↓の式は「A:B=C:DのときBC:AD」を使いました。 5(3X-4Y)=1(X-2Y) 15X-20Y=X-2Y 15X-X=-2Y+20Y 14X=18Y 両方を2で割る 7X=9Y X:Y=7:9 になりましたが、誤りだそうです。 回答は反対のX:Y=9:7になっています。 質問なんですがX:Y=7:9が→X:Y=9:7にするには 何か計算したり、動かしたり、公式に入れたりしているの でしょうか?そのあたりを※詳しく詳しく教えてください。 (※は投稿するとどうも端に寄ってしまうので、わざと※を付けて寄らないようにしています。計算とはまったく関係ありませんので) ご指導よろしくお願いします。

  • UWSCのスクリプトについて

    画像Dを認識したら画面上に画像Bがあっても 処理Bを実行しない為にはどうしたら良いでしょうか。 -------- while True BTN(LEFT,click,150,10,110)   //処理A Sleep(2) ifb CHKIMG("A.bmp")    x=G_IMG_X            y=G_IMG_Y BTN(left,click,x,y,110) Sleep(1.5) endif Ifb ChkImg("B.bmp")       //処理B BTN(LEFT,click,1120,90,110) Sleep(1) KBD(VK_return,DOWN,30) endif ifb CHKIMG("C.bmp")      //処理C x=G_IMG_X            y=G_IMG_Y BTN(left,click,x,y,110) Sleep(1.5) wend --------

  • 分数式での疑問

    x^2-xy-cy+cx / x^2+bx-xy-by =x(x-y)+c(x-y) / x(x-y)+b(x-y) =(x-y)(x+c) / (x-y)(x+b) =x+c / x+b ↑の式が納得できませんでした。 2行目の x(x-y)+c(x-y) / x(x-y)+b(x-y) を、 x(x-y)で約分して ⇒c(x-y) / b(x-y)  更に(x-y)で約分して c / b と答えたのですが、どこで間違ったのでしょう。 x(x-y)+c(x-y) / x(x-y)+b(x-y) ↑ここで分母と分子を (x-y) で括らなければ答えが間違ってしまうのは何故ですか?

  • 数学(ベクトル)の問題

    http://okwave.jp/qa/q8022847.html のNO.7の回答より、 さらに途中式を書いたのですが、 L^2 = m(t-n(s))^2-(a1^2+b1^2+c1^2 ) {(c1(z2-z1)+b1(y2-y1)+a1(x2-x1)+(a1a2+b1b2+c1c2)s)/(a1^2+b1^2+c1^2 )}^2+(a2^2+b2^2+c2^2 ){(s^2 )+2s{c2(z2-z1)+b2(y2-y1)+a2(x2-x1)}/{(a2^2+b2^2+c2^2 )} }+{(x2-x1)^2 }+{(y2-y1)^2 }+{(z2-z1)^2 } n(s)={c1(z2-z1)+b1(y2-y1)+a1(x2-x1)+(a1a2+b1b2+c1c2)s}/(a1^2+b1^2+c1^2 ) = m(t-n(s))^2-{c1(z2-z1)+b1(y2-y1)+a1(x2-x1)+(a1a2+b1b2+c1c2)s}^2/(a1^2+b1^2+c1^2 )+(a2^2+b2^2+c2^2 ){(s^2 )+2s{c2(z2-z1)+b2(y2-y1)+a2(x2-x1)}/{(a2^2+b2^2+c2^2 )} }+{(x2-x1)^2 }+{(y2-y1)^2 }+{(z2-z1)^2 } = m(t-n(s))^2-{c1(z2-z1)+b1(y2-y1)+a1(x2-x1)+(a1a2+b1b2+c1c2)s}^2/(a1^2+b1^2+c1^2 )+(a2^2+b2^2+c2^2 )(s^2 )+2s{c2(z2-z1)+b2(y2-y1)+a2(x2-x1)}+{(x2-x1)^2 }+{(y2-y1)^2 }+{(z2-z1)^2 } ところで {c1(z2-z1)+b1(y2-y1)+a1(x2-x1)+(a1a2+b1b2+c1c2)s}^2 = {c1(z2-z1)+b1(y2-y1)+a1(x2-x1)}^2 +2{c1(z2-z1)+b1(y2-y1)+a1(x2-x1)}(a1a2+b1b2+c1c2)s +{(a1a2+b1b2+c1c2)s}^2 = {c1(z2-z1)+b1(y2-y1)+a1(x2-x1)}^2 +2{c1(z2-z1)+b1(y2-y1)+a1(x2-x1)}(a1a2+b1b2+c1c2)s +(a1a2+b1b2+c1c2)^2 (*s)^2 これより、 L^2= m(t-n(s))^2+s^2 {(a2^2+b2^2+c2^2 )-(a1a2+b1b2+c1c2)^2/(a1^2+b1^2+c1^2 )} +s[2{(c2(z2-z1)+b2(y2-y1)+a2(x2-x1))-{c1(z2-z1)+b1(y2-y1)+a1(x2-x1)}(a1a2+b1b2+c1c2)s/(a1^2+b1^2+c1^2 )}] +{(x2-x1)^2 }+{(y2-y1)^2 }+{(z2-z1)^2 }-{c1(z2-z1)+b1(y2-y1)+a1(x2-x1)}^2/(a1^2+b1^2+c1^2 ) 簡単、 L^2 =m(t-n(s))^2+ps^2+p1s+p2 =m(t-n(s))^2+p(s^2+p1s/p)+p2 =m(t-n(s))^2+p(s^2+p1s/p+(p1/p)^2-(p1/p)^2 )+p2 =m(t-n(s))^2+p(s^2+p1s/p+(p1/p)^2 )-(p1)^2/p+p2 まで、計算したのですが(間違っていたら申し訳ありません)、 ここから、どのように q=-p1/2p が導出できるのかがわからないです。 (rは導出できました。) 数式だらけで分かりづらいと思いますが、計算ミスを指摘しつつ、導出過程も分かりやすくお願いします。

  • 分数方程式の変形

    yはxの関数で、a,b,cが0でない定数のとき y=ax-b/x-c を y(x-c)=ax-b と変形することはどんなときでもできますか? 自分は変形できると思うのですが、 もし、変形できない場合があれば、教えてください。

  • 座標の問題

    放物線A:y=2x^2+6x-8と直線B:y=5x+13がある。放物線AとY軸との交点をa、直線BとY軸の交点をb、放物線Aと直線Bとの交点でx座標、y座標とも正である点をcとし、a、b、cを頂点にした三角形を三角形abcとする。このとき、点bを通り三角形abcの面積を2等分する直線とX軸の交点のx座標はいくらか。 という問題があるのですが、AとBにそれぞれx=0を代入し、aとbを出すとこまでは出来たのですが、cを出すのがわかりません。 cの出し方とその後の計算方法を教えてください。

  • エジプトの分数問題。どうしても解きたい。

    4abc-b-4c∈K , 4abc-b-c∈H , x*y∈T , x≠1、y≠1 Tは素数以外の数で可解集合とする。 ここで、P+k=4abc-b-c∈H とすると 1≦c=4m-k≦4 とする。 P+3=4ab(4m-3)-b-4m+3 , P∈K P+6=4ab(4m-6)-b-4m+6 , P∈K P+7=4ab(4m-7)-b-4m+7 , P∈K P+ 12=4ab(4m-12)-b-4m+12 , P∈K ここで、15n+aの形の関数を考える。 すると 15n+1∈K、P+12 15n+2∈K、P+12 15n+3∈T、3 15n+4∈K、P+7 15n+5∈T、5 15n+6∈T、3 15n+7∈K、P+7 15n+8∈K、P+3 15n+9∈T、3 15n+10∈T、5 15n+11∈H 15n+12∈T、3 15n+13∈H 15n+14∈H 15n+15∈T、15 ここで具体的に15n+1=pを計算してみましょう。 P+12=4abc-b-c=(4ac-1)*b-c b=n+1,a=2,c=2 P+12=15n+15-2=15n+13∈H P+12=4ab*4-b-4∈H P=4ab*4-b-4*4∈K このように計算していくと15n+aは解けることになります。 自信はないのですが。 また、わけわからないことを言って迷惑をかけています。 先に謝っておきます。どうもすみません。 本人はこんな簡単に解けるはずはないと思っています。