1/0を数学的、教育学的、プログラム的に考える

というわけで今回は三種すべてに絡んだネタをやっていきたいと思います。この頃いろいろな場所でこの「ゼロ除算」の話が書いてあったのでそれがあり得る環境としてこの3つで書いていきたいと思います。というかゼロ除算で問題になるのは大別するとこの3つになるような気がしないでもありません。

 

数学的にはどのように扱うか、をおさらいする

まずこれが大切です。ここの認識が誤るとその後ろの2つについて「なぜそういうことになるのか?」を説明できなくなる可能性が高いからです。注意していきましょう。

まず数学的に1/0を考える場合、この演算を代数学を主としてとらえるか解析学を主としてとらえるか、によってかなり差が出ます。基本的には代数学の考え方が主となるのですが…。

 

代数学の考え方で1/0を考える

代数学で1/0を考えるときはたいていの場合『「1」や「0」は整数と考えてその中に自然に定義される(乗法の逆演算である)除法を用いて演算せよ』という問題と考えることができます。ここで問題となるのが「整数」や「乗法」および「逆演算」をどう考えるか、にあります。そもそも代数学では0や1は実は形式的な記号と考えることができます。また、今回の場合「整数」を対象としたとしてその場合乗法だけではなく加法も同時に定まっていると考えるとこの演算は「整数環、あるいは有理数体(実数体、複素数体)上で」という制約がさらに考えられる、というところまで考えないと正しく考えることができません。

で、ここまで来て初めて公理系から考えていきます。必要となるのは環の公理および体の公理です。まずは環の公理から。Wikipediaにある環の公理とは少し違いますが私の持っている教科書の書き方に準拠します。

加法と乗法という2つの演算が定義された集合Rが環(ring)であるとは次の4つの条件を満たすことである。(この4つを「環の公理系」と呼ぶ)

  1. Rは加法に関して加群である。
  2. Rは乗法において結合法則を満たす。
  3. Rは乗法と加法において分配法則を満たす。
  4. Rは加法の単位元0Rとは異なる元1Rが存在しに対してを満たす。

ちなみにこの公理から証明される定理として

加法の単位元0Rに対してとなる

があります。次に体の公理です。

環Rにおいて以下の条件を満たすときRは体(field)であるという。

  1. Rは加法の単位元0Rを除いて乗法において逆元を持つ。
  2. Rは乗法において交換法則を満たす。

で、ここまで見てみると気がつくと思いますが「0の逆元は体の公理系では定義されていない」ということです。わざわざ体の公理でも「0Rを除いて」ということになっています。このことから代数学的には体において「1/0」という操作は定義されていない(考えない)ということになっています。また環で考えたとしても除法は乗法の逆演算として考えるのでこの場合は考えることができない代物になっています。演算ができないというよりは考えない、が正しいです。ちなみに上記からわかると思いますが0/0も代数学の環や体では定義されません。

 

解析学的の考え方で1/0を考える

で、これで終わらないのが数学です。代数学的にはそうなのですが、解析学的には極限の考え方を用いることでいくつかの場合によって値を考える、ということを行います。つまり直接的に1/0は定義されていないとしても0にごく近い範囲で考えれば除数は0ではない限り乗法において逆元を持つ(有理数体や実数体より)ので0に近づけていくとどうなるのか?というものです。

たとえば関数を考えてxを1から0に正の数として近づけて答えを考えます。すると

  • 1/1=1
  • 1/0.1=10
  • 1/0.01=100
  • 1/0.001=1000

のように答えが大きくなっていっているのがわかります。これを続けていくなら1を一つ前に考えていた数より0に近い正の数で除法を行うと一つ前の答えより正の数として絶対値が大きな値となりどこかで一定の答えとなることはないという結論が得られます。で、これを極限の書き方で書くととなるわけです。なお、この無限大(∞)という書き方ですがこれは数ではなく状態を表す記号です。そのため数としての演算は一切できません。

ただ注意が必要なのが今は「正の数として」近づけていきましたが逆に「負の数として」近づけてみるとどうなるでしょうか。xを-1から0に負の数として近づけて答えを考えると

  • 1/(-1)=-1
  • 1/(-0.1)=-10
  • 1/(-0.01)=-100
  • 1/(-0.001)=-1000

ということで想像できると思いますがこの場合は1を一つ前に考えた数より0に近い負の数で除法を行うと一つ前の答えより負の数として絶対値が大きな値となる、という結論が得られます。上と同様に極限の書き方で書くととなります。

関数の場合は実は近づけ方によってx=0の極限を考えると複数の答えが出てきてしまします。そのため、解析学的にも極限を考えたとしてもx=0における極限は存在しない、という解答となります。(ただし正の方向から近づけた場合は正の無限大、負の方向から近づけた場合は負の無限大という解答にはなります)

おまけですが、解析学的として0/0を考えるといろいろと大変なことが起こります。たとえば関数を考えるとx=0では0/0の形となり値を持たない、となりますが極限を考えれるととなりnの値に依存した答えとなります。これだけ見てもわかりますが0/0を見ただけでは極限値がどうなるか解析学的にもわからないわけです。

 

教育学的にはどう扱うべきなのか考察する

問題なのはここですよね…。このセクションについては完全に個人的見解となりますのであしからず。

まず、学習指導要領および学習指導要領解説にゼロ除算について何か書いていないかな~?と思って読み解いてみたのですがさすがにその部分は疑問に持つ児童や生徒はいたとしても学習する項目としてではないので言及は一切ありませんでした。このことからもし児童や生徒に質問された場合どう返すか、は先生の考え方および力量に依存することになると考えられます。

次に除法を学習するときにどうやって学習するか、からゼロ除算について何かいい言い方がないのか?を考えてみました。気になったのが小学校三年生での除法と乗法、減法との関係についてで、12÷3の意味を考える場合に、

包含除は3×□=12の□を求める場合であり、等分除は□×3=12の□を求める場合である。また、実際に分ける場合でも、包含除も等分除と同じ仕方で分けることができることなどにも着目できるようにしていくことが大切である。

とあるので、ゼロ除算を除法について習ったばっかりなら「じゃあ1÷0の答えを考えてみるけれども0×□=1となる□に当てはまる数はある?ないよね?だから0でわることはできないんだよ」というよくある教えかたがこの場合は適しているといえそうだ、と考えました。また減法との関連であまりが出る除法においてもカードを分ける場合などの例を使うことから「カードを配るやり方で1÷0を考えてみるけれども、一枚のカードを一人に一枚も配らないで配ったふりだけをすると何回できる?(なんか不思議に思えるけれども)何回でもできるよね。そうすると答えが出そうにないね」という言い方になるのでは?と考えました。

ちなみにこの考え方ですが、前者の言い方は数学的には代数学における「0の逆元は定義されていない」を形式的に説明したものであり、後者はどちらかというと解析学における正の数から0に近づけていったときの極限の考え方に近い説明だと考えています。

なお、この後文字と式で文字を使った式を学んだり、方程式で式の変形を考え始めるといつの間にかゼロ除算をしてしまったパターンが現れてくることもあり、そのときは「ゼロ除算となる場合を分けて考えないと正しくない答えが入ってしまうね。これはゼロで割る、ということができない(定義されていない)からこうなるのだよ」という説明はできそうな気がします。高校レベルでも極限までいければだいぶ説明がしやすいですが…。

 

最後にプログラム的にはどうなる?

実はいろいろなコメントを読んでいて一番気になったのがこのポイント。「1/0はDivision by zeroでエラーとなる」という発言が多かったです。ただし注意してほしいのが(たいていの人は理解して言っていると思いますが)対象のプログラミング言語や変数の型によっては必ずしもそうではない、ということを書いておきたいと思います。

以下のC言語のサンプルコードはすべてゼロ除算をしているパターンです。

#include <stdio.h>

int main(void)
{
        printf("1.0/0.0=%f\n",1.0/0.0);
        printf("1.0/(-0.0)=%f\n",1.0/(-0.0));
        printf("0.0/0.0=%f\n",0.0/0.0);
        printf("1/0=%d\n",1/0);
        return 0;
}

これをgccでコンパイルしてみました。ファイル名をtest.cとしてやってみると

$ gcc test.c
test.c: 関数 ‘main’ 内:
test.c:8:21: 警告: ゼロ除算が発生しました [-Wdiv-by-zero]
  printf("1/0=%d\n",1/0);

となります。警告が出ているのは実は一番最後の1/0だけで残りの1/0や0/0は警告が出ていません。さらにできたファイルを実行してみます。

$ ./a.out
1.0/0.0=inf
1.0/(-0.0)=-inf
0.0/0.0=-nan
Floating point exception (コアダンプ)

例外により強制終了しているのは最後の演算だけで、残りの3つに関しては(一応)答えを出しています。これはどういうことかというと浮動小数型の場合はIEEE754にもありますが無限大やNaN(Not a Number、非数)が定義されていて、浮動小数として演算を行った場合はそれぞれ解析学的に極限を考えたものとして計算する、という動作になります。0/0の場合は極限が不定となるためにその状態として非数を用いて表現されているのがわかります。浮動小数型の場合は科学技術演算や3D演算等で無限大を考える必要があるのでこの方が都合がよいのでしょう。また整数型の場合は代数学的に計算されると考えればよいようで、そうなるとゼロ除算の結果は定義されていないため直接わかる場合はコンパイラによる警告が表示され、実行時では例外となるわけです。

 

ちなみにスクリプト言語としてPHPでやってみるとどうなるか、というとこういうコードで試してみました。

<php
  print 1/0;
?>

これをtest.phpに保存して実行してみると

$ php test.php
PHP Warning:  Division by zero in /…/test.php on line 2
INF

ということでゼロ除算による実行警告は出てきましたが計算結果としてはINF、つまり正の無限大となったわけです。なのでこの処理をただの警告と処理するなら常に「エラーとなる」訳ではなく、処理をそのまま継続することが可能です。このあたりは注意して扱う必要があります。

 

本当に考えるのであれば数学上での考え方を基礎にして考える必要があり

高校以下の数学および算数やプログラムでもそうですが、元となる数学の考え方をそれぞれに落とし込んだものですので元の考え方を知らないと理由を突き止めることは難しくなります。もちろん結果そうなるだけで納得できるならそれはそれでもいいですが、深く知っておくと似たような場面で理由が連想できるようになり、人に説明するときにうまく説明できるようになったり自分で問題が起こったときに学ぶことができるようになると思います。

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

この記事のトラックバック用URL