LogoMark.png

DivisionByZero

Division by Zero

未定義の演算

Division by Zero(ゼロ除算)は、0で割る演算のことです。通常の算術においては未定義の演算で、コンピュータプログラムの世界では、処理中にエラーを発生させてしまう「やってはいけない」演算です。


プログラマーの必須知識

コンピュータによる計算処理では 「0 で割る」という状況が生じると、Division by Zero Error になってしまいます。よって、変数による割り算が生じる部分では、分母となる変数が0となる場合を回避するような手続きが必要になります。

以下のプログラムは、一見、問題なさそうに見えますが、x の部分に引数として 0 が渡されるとエラーになってしまいます。

funciotn calc( x, y ){
    var z = y / x;
    return z;
}

一般に、以下のように、分母の状態をチェックする手続きが必要です。

funciotn calc( x, y ){
    if ( x != 0 ){
        var z = y / x;
        return z;
   } else {
       // 分母が 0 となってしまう場合の例外処理
   }
}




Division by Zero が関わる迷問題

両辺に同じ処理を施しただけなのに・・

a = b とします。
1) 両辺に a をかけると、
a 2 = ab
2) 両辺に a 2 - 2ab を加えると、
2a 2 - 2ab = a 2 - ab
3) 式を整理すると
2 ( a 2 - ab ) = ( a 2 - ab )
4) 両辺を a 2 - ab で割ると
2 = 1
というおかしなことがおこります。
式の変形、どこにトラップがあるのでしょうか?*1


ピタゴラスの定理の延長に・・

ピタゴラスの定理とは、「 直角三角形の3辺の長さの関係において、斜辺の長さを z, 他の2辺の長さを x, y とすると、x,y,z には x 2 + y 2 = z 2 の関係が成り立つ 」 というものです。さて、ここで、これを x,y,z という3変数の方程式と考えると、この関係を満たす自然数には、例えば x = 3, y = 4, z = 5 があります。

さて、この関係式を拡張して、2乗のかわりに 1乗や、3乗、4乗・・を考えてみると、x + y = zx 3 + y 3 = z 3 ・・と、いずれも、特段問題のない方程式を書くことができます。

ところが、n=0 の場合を考えると・・
x 0 + y 0 = z 0  つまり 1 + 1 = 1
という、書いてはいけない数式になってしまいます。

通常0乗とは、a / a ( a1 x a -1 )のことで、その値は1です。左辺のいずれかの項が 0 となる、あるいは、すべての項が 0 となること、つまり 0 0 = 0 としてよければ、解が存在しますが、これは、0 / 0 というDivision by zero問題を含んでいて、普通に扱えない対象となります。通常、指数関数 a x は実数 (1 ≠ ) a > 0 と x に対して定義されているため、0 0 はこの意味では定義されていません。

いくつかのプログラミング言語は 0 0 を定義しており、その多くは 1 としているので、そのまま適用するとおかしなことになってしまいます。

ことのついでに
ちなみに、有名なフェルマーの最終定理は、ピタゴラスの定理の「2乗」を「n乗」に拡張した場合、つまり、x n + y n = z n に関する思考の結果生まれたもので、「 3 以上の自然数 n について、x n + y n = z n となる自然数の組 (x, y, z) は存在しない 」 すなわち、ピタゴラスの定理を満たす 3, 4, 5 のような「三つ組数」は存在しない・・という、意外にもシンプルなもの。
 17世紀フランスの数学者ピエール・ド・フェルマーが提唱したこの定理自体は、いたってシンプルなものですが、360年もの間、多くの数学者をして証明も反証もかなわず、長く「フェルマー予想」と称されていました。
 これを証明したのは、アンドリュー・ワイルズ(Andrew Wiles, 1995)。その論文、 “Modular elliptic curves and Fermat's Last Theorem(モジュラー楕円曲線とフェルマーの最終定理)”は、現代数学の知見を総動員した100ページ越えの論文で、これを理解・検証できる数学者は多くはありません。



余談1:数直線上の境界「1」

数直線上の 1 の前後は連続していない?
0.9999 > 1 > 1.0001 は、何の問題もなく連続しているように見えます。
しかし、以下の処理を施すと、そこには大きな亀裂があることがわかります。
lim [ n → ∞ ] x n


余談2:複素平面上の境界

Z と C を複素数として、以下の漸化式を繰り返すことを考えます。
Z n+1 ← Zn2 + C
n ← n + 1

この計算を Z の初期値 Z0 = 0 として一定回数繰り返した場合(例えば100回程度)、定数Cの値によって、域外へ発散する場合と、そうでない場合があるのですが、その境界となる場所が、非常に複雑かつ再帰的な曲線になることが知られています。

複素平面上の縦横とも ±2の範囲で、すべてのC( a + bi )について、上記の計算で発散するか否かを調べ、発散しない場合のCの点(a,b)を塗り分けると、以下のような図形になります。発見者の名をとって「マンデルブロ集合」と呼んでいます。




PAGES

GUIDE

DATA


*1 問題があるのは、プロセスの 4) です。a=b の前提があるので a 2 - ab は 0。つまり、このプロセスでは、Division by zero を行っていて、これが論理展開を破綻させています。この処理、実はすでにプロセスの 2) の時点で 0 = 0 という式になっていて、プロセス 3) までは、a=b を解とする方程式になっています。
Last-modified: 2020-02-02 (日) 17:35:08