LogoMark.png

DivisionByZero の変更点


#author("2020-02-02T17:35:08+09:00;2019-12-25T12:53:01+09:00","default:inoue.ko","inoue.ko")
*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 をかけると、
'''''aSUP{ 2}; = ab'''''
2) 両辺に aSUP{ 2}; - 2ab を加えると、
'''''2aSUP{ 2}; - 2ab = aSUP{ 2};  - ab'''''
3) 式を整理すると
'''''2 ( aSUP{ 2}; - ab ) = ( aSUP{ 2}; - ab )'''''
4) 両辺を aSUP{ 2}; - ab で割ると
'''''2 = 1'''''
というおかしなことがおこります。
式の変形、どこにトラップがあるのでしょうか?((問題があるのは、プロセスの 4) です。a=b の前提があるので aSUP{ 2}; - ab は 0。つまり、このプロセスでは、Division by zero を行っていて、これが論理展開を破綻させています。この処理、実はすでにプロセスの 2) の時点で 0 = 0 という式になっていて、プロセス 3) までは、a=b を解とする方程式になっています。 ))

~

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

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

ところが、n=0 の場合を考えると・・
'''''xSUP{ 0};  + ySUP{ 0}; = zSUP{ 0}; ''''' つまり '''''1 + 1 = 1''''' 
という、書いてはいけない数式になってしまいます。

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

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

''ことのついでに''
ちなみに、有名な''フェルマーの最終定理''は、ピタゴラスの定理の「2乗」を「n乗」に拡張した場合、つまり、'''''xSUP{ n};  + ySUP{ n};  = zSUP{ n}; ''''' に関する思考の結果生まれたもので、'''「 3 以上の自然数 n について、''xSUP{ n}; + ySUP{ n}; = zSUP{ 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 → ∞ ] xSUP{ n}; '''''
-x < 1 の場合は 0
-x = 1 の場合は 1
-x > 1 の場合は ∞

~

**余談2:複素平面上の境界
Z と C を複素数として、以下の漸化式を繰り返すことを考えます。
'''''ZSUB{ n+1}; ← ZSUB{n};SUP{2}; + C'''''
'''''n ← n + 1'''''

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

複素平面上の縦横とも ±2の範囲で、すべてのC( a + bi )について、上記の計算で発散するか否かを調べ、発散しない場合のCの点(a,b)を塗り分けると、以下のような図形になります。発見者の名をとって「マンデルブロ集合」と呼んでいます。
-[[GoogleImage:マンデルブロ集合]]
-[[デモプログラム>https://design.kyusan-u.ac.jp/SampleSite/p5js_MandelbrotSet/]]

~

~


~