抜粋翻訳 PEP 238: Changing the Division Operator

概要

現在の除算演算子 (/) は数値を引数として使った場合の意味が曖昧である。引数がintやlongの場合には、数学的な除算の結果を切り捨てたものを返す。しかし、引数がfloatやcomplexの場合には除算の結果の妥当な近似値を返す。

この異なる演算のために異なる演算子を導入することによってこの問題を修正することを提案する: x/yを数学的な除算の結果の妥当な近似値を返す除算(真の除算), x//yを切り捨てた値を返す除算(切り捨て除算)とする。現在の、意味の混ざった x/y を「従来の除算」と呼ぶ。

動機

従来の除算命令では任意の数値入力に対して正しい結果を返す数式を書くのが困難である。他の演算子全てに関しては x*y**2 + z などの式を書くことができ、どんな数値型(int, long, float, または complex)の入力であってもその計算結果は数学的な結果に近い(もちろん計算精度の範囲内で) しかし除算は問題を起こす。もし運悪く除算の両方の引数が整数型だったら、真の除算ではなく切り捨て除算になってしまう。

この問題は動的型付け言語に特有のものである: Cのような静的に片付けされた言語では、入力(多くの場合関数の引数)はdoubleやfloatであると宣言されているだろう。そして整数を引数に渡して呼び出した場合、呼び出し時にdoubleやfloatに変換される。

訳注

これは個人的には「なぜそんな変更をしたのか謎だ」と思っていた、1 / 2 == 0.5 への変更についてのPEPだ。何が問題だと考えてこの変更を行ったのか腑に落ちた。

しかし、OCamlみたいに「そもそも整数の演算と浮動小数点数の演算が別物なんだから全般的に演算子を分けるべきじゃないか」という意見や、Haskellみたいに「そもそも整数と浮動小数点数の演算を許しているのが問題なんじゃないのか」という意見、Schemeみたいに「いや1/10を0.1にした時点ですでに正しい計算じゃないだろ」という意見もあり、この解決方法が唯一の正解とはいえない。

数の構造をどうやって言語の中にモデル化するか、という難問なんだな。