ゼロ除算発生時にデフォルトの値を返すようにしたら、深刻な問題が発生する? 199
ストーリー by headless
除算 部門より
除算 部門より
プログラムでゼロ除算が発生したときに、何らかのデフォルト値を返すようにすることは有害かどうか、というAsk Slashdot記事に1,000件以上のコメントが付き、大いに盛り上がっているようだ。
話としては、ゼロ除算のチェックに疲れ果てたベテランプログラマーが、ゼロ除算発生時に「0」を返すなどの処理をシステム全体のデフォルトとして設定することを夢見るというもの。0以外ではどのような値がゼロ除算の結果として適切か、とも尋ねている。皆さんのご意見はいかがだろうか。
話としては、ゼロ除算のチェックに疲れ果てたベテランプログラマーが、ゼロ除算発生時に「0」を返すなどの処理をシステム全体のデフォルトとして設定することを夢見るというもの。0以外ではどのような値がゼロ除算の結果として適切か、とも尋ねている。皆さんのご意見はいかがだろうか。
一部の世界では正しい (スコア:5, 参考になる)
> ゼロ除算発生時に「0」を返す
「9÷0=」の答えは? 小学校算数で出題された問題めぐりネット上で議論
2012年11月28日(水) 18時46分
http://www.rbbtoday.com/article/2012/11/28/98481.html [rbbtoday.com]
Re:一部の世界では正しい (スコア:2, すばらしい洞察)
> 一部の世界では正しい
正しいなんて書いてないです。
「9÷0=0」と教えている小学校もあると書いてあるだけです。
Re:一部の世界では正しい (スコア:2)
数学は公理で体系が決まるので、公理として「0で除算した結果は0」と決めれば正しくなる。
その上で、「0で除算した場合は除算記号の除去を認めない」も公理として追加すれば、一応体系は成立するかと。
-- Buy It When You Found It --
Re:一部の世界では正しい (スコア:2)
0で割ると0だけど0/0は定義できない、他はそのままって公理系を定義しようとしているんでしょうけど、well-definedにはできないと思いますよ。a,bを不定定数として、
ax = b
x = b / a
これはaが0の場合は最初の式が0=bになってしまい成り立たないけど
下の式は x=0になって普通に解が得られてしまう。つまり下の式への変形はa=0を最初に除外しないといけない。しかもa=0だと解無しのまま。せっかく0の除算を定義したのに。
解の公式もそうだし、他でも色々矛盾が出てきますよ。
Re:一部の世界では正しい (スコア:2)
上の式を下の式に変形する際に、「除算記号の除去」が行われていますよね。
a=0の場合、これが禁止されるので、上の式と下の式は等価ではないって事で、一応辻褄は合ってる様な気がします。
尤も、既存の公式が崩壊するという点では同意します。
ま、「記号の除去の禁止」が凶悪な足枷となって、二重否定の除去を禁止する直感論理の様な弱い体系になるのは確実なんですが。
-- Buy It When You Found It --
Re:一部の世界では正しい (スコア:1)
>「9÷0=0」と教えている小学校もあると書いてあるだけです。
・・・と教えている「小学校教員もいる」・・・
が正解なんでしょうね。
その教員が小学校~教員に至るまでの過程できちんとした算数・数学の教育を受けられなかったか誤った知識のままで、教え子達にもその誤った知識を拡散していってるんだろうなぁ。
#なんとなく、悪貨は良貨を駆逐する
Re:一部の世界では正しい (スコア:2)
0 ÷ 0 が0なのか1なのかで迷ったりと色々波紋を呼びそうですね。
反比例とか原点を通る線をひいちゃったりするんだろうか?
Re:一部の世界では正しい (スコア:2)
下記にようにWikipediaには書いてある。けど、Javaで 0 / 0 をやると例外が発生します。
0の0乗
https://ja.wikipedia.org/wiki/0%E3%81%AE0%E4%B9%97 [wikipedia.org]
いくつかのプログラミング言語は 00 を定義しており、その多くは 1 としている。1 と定義しているものは、Java、Python、Ruby、Perl、Haskell、Common Lisp、ML、Scheme、R、MATLAB、APL、J、Microsoft Windows の電卓、Google の電卓機能[4]などである。
Re:一部の世界では正しい (スコア:2)
間違えた。こっちだ。
ゼロ除算
https://ja.wikipedia.org/wiki/%E3%82%BC%E3%83%AD%E9%99%A4%E7%AE%97 [wikipedia.org]
現在のほとんどのコンピュータでサポートされているIEEE 754 浮動小数点に関する標準規格では、全ての浮動小数点演算を定義している。ゼロ除算も例外ではなく、どういう値になるかが定義されている。IEEE 754の定義によれば、a/0 で a が正の数であれば、除算の結果は正の無限大となり、a が負の数であれば負の無限大となる。
Re:一部の世界では正しい (スコア:2)
A÷B=C ⇔ A=B×C
が定義ですから
0÷0=C は 0=0×C と置き換えられ
このCに、無理数どころか複素数を代入しても成り立つので
Re:一部の世界では正しい (スコア:1)
うちらのころは、のらりくらりと興味を持たないように教えてたかなぁ。
中学校になって止めろと教わったっけか。
Re:一部の世界では正しい (スコア:2, 興味深い)
> うちらのころは、のらりくらりと興味を持たないように教えてたかなぁ。
30年前小学校で
「10個のりんごを10人で分けたら、1人1個ですね」
けど
「10個のりんごを0人で分けれないし、1人の個数の答え出ないですね」
って教えてました。
Re:一部の世界では正しい (スコア:1)
Android4.4.2の電卓でゼロ除算は「∞」になりますね
他のバージョンやiOSはわかりませんが
Re:一部の世界では正しい (スコア:1)
子供が9÷0を0と習ってきました。
去年の話です。
子供には、即座に間違いを指摘しましたが、
上の子2人に確認したところ、違う先生から0と教わってきていました・・・レベルが低すぎる
Re:一部の世界では正しい (スコア:1)
正しくは1ですか?0÷0の答え。
Re:一部の世界では正しい (スコア:2)
正しくは「定義できない」
プログラミング言語ならNaNか例外を返すべきかな。
割り算させない (スコア:5, 参考になる)
リアルタイム信号処理のプログラム書きますが、
立ち上がってすぐは入力データが用意されていないでクリアしたバッファの初期値で演算
(たとえばパイプラインADCとか使っていて入力に遅延がある)
なんてことは普通にあり得るので、アルゴリズム中に割り算があるとき
(正規化とかAGCとか)では 0割が発生しないように 除数がゼロかどうか
あらかじめチェックします。そして、結果を後段アルゴリズムの制約上問題ない値とします。
例外なんて起こさない方がいいし、誰か書いていましたがそんな機構は無い場合もあるしで
予測される例外は基本的に排除(生起しないように手を打つ)すべきです。
データが用意されるまで待てばいいんだけどね。
演算側の水際でも処置しておかないと安心できない
つーか、後段の用途によって0割の結果値を吟味するのって普通だと思いますが
(0で駄目なら非0の微小値とかそもそものアルゴリズムをスキップするとか)
そういうこと考えないでプログラム書いてるんですかね。
Re:割り算させない (スコア:1)
業務計算のプログラムとか除算の嵐です。
しかも本来そこに、データエラーでない限り、0はありえないという場合も多い。
ありえないので処理しない、テストもしないというわけ。
で、データエラーというのは頻繁に起こるわけです(爆笑)
笑ってる場合ではないですが。
Re:割り算させない (スコア:1)
>しかも本来そこに、データエラーでない限り、0はありえないという場合も多い。
>ありえないので処理しない、テストもしないというわけ。
みずほ銀行の問題が未だに収拾ついていないらしいのって、こういう文化圏の人が仕切ってるからじゃないかという気がしてならないのですが(^_^;
まぁ、そういう文化圏の会社の仕事やったことあったから書いてるのですが(;´Д`)
Re:割り算させない (スコア:1)
>必要なのは分かってるが、堅牢にしようとすればチェック処理の方が多くなるのはもやっとしません?
堅牢なことは至上命題で大前提だと思いますよ。高速化とかエレガントなアルゴリズムとかは、その後についてくると思ってます。
だから、殆どもやっとはしないです、個人的には。
まぁ、この手のチェックや回避策の処理自体をミドルウェアや言語系でやってくれると助かるんですけどね。
なんで誰も気づかない (スコア:4, おもしろおかしい)
チャック・ノリス [wikipedia.org]に答を聞けばいいだろうに。
……いや、だから…… (スコア:3)
その人が作ろうとしてるプログラムにおいて、0除算が発生した時に、どう云う動作をするのが「正しい」の??
話は、それからだ。
Re:……いや、だから…… (スコア:1)
まさにこれ。
ゼロで除算した結果をどう扱いたいかなんて、完全にドメイン依存だと思うんだがなー。
チェックコードに忙殺されて主題に集中できない言語・環境に疲れ果てている、という状況には同情する。
Re:……いや、だから…… (スコア:1)
どういう振る舞いが正しいにせよ、割り算するたびにチェックするのは疲れるから、ゼロ除算発生時の振る舞いをオーバーライドできるといいなあという話だと思います。
デフォルトの振る舞いはエラー終了でいいと思いますけど。
Re:……いや、だから…… (スコア:2)
計算結果を何に使うかで変わってきますよ。
3D空間の座標系計算のような場合は、0が引数に入ってきた場合を始めにトラップして、想定している範囲の最大の数値を返したりとかやりますよ。
組み込み系の場合には、自分で仕様書く場合は0が突っ込まれないように回避策を考えたりもしますし、仕様書が上から降ってくる場合には「0で割り算する可能性があるんだけど、その場合どうします?(´・ω・`)」とコードを書いてる時でもお伺いを立てたりもしましたよ。
要は、データ構造を作る段階で、可能ならば、割り算の分母に0が突っ込まれた場合の数値とかトラップ処理とかを入れ込んで考える必要があると言う事で。
エラーでプログラムが異常系に行くとか止まっちゃうとかAssertで強制終了しちゃうというのは、最悪のシナリオだという感覚がどうしてもありますけどね。分母0の割り算でそうなってしまうのは、ヌルポインタでそうなるのと同じ位「ダサい」と言う感覚が。
Re:……いや、だから…… (スコア:1)
やっぱり、「ABEND」 じゃないとわかり辛いですよね。
画像処理 (スコア:3)
0だと目に見えておかしくなると思う。
そういうのがGIMPでもあったので一律0は広めてほしくない。
仕様次第かな? (スコア:2)
> ゼロ除算発生時に「0」を返す
よりもバリデーションでゼロ除算を発生させない方向には向かえないんですかね?
Re:仕様次第かな? (スコア:2)
> >ゼロ除算のチェックに疲れ果てた
> からでは?
どんなシステムかはわかりませんが、
入力値のバリデーションがチェックに疲れるほどあるシステムに問題がありますね。
もうつくっちゃったから仕方がないのですかね?
Re:仕様次第かな? (スコア:2)
いやいや、いくらでもあるでしょう。
プログラム中割り算なんていくらでも使うし、その割る数が入力値じゃないケースの方が圧倒的に多いし、それが理論上0になる可能性がある場合なんていくらでもあるでしょう。
例えば実行件数を時間の差分で割る場合とか、時間の差分はOSの時刻を変更されたら0になることだってあり得ますよね?
それでいいなら世の中にバグなど存在しないことになる (スコア:2)
それを「よくわからないから」という理由で「無かった」ことにするのが正しいか、
と言ってるの?正気ですか?
#真面目に言ってるとしたら、馬鹿の戯言
深刻な問題=深刻なバグ? (スコア:2)
Re:深刻な問題=深刻なバグ? (スコア:2)
> 仕様からして値がゼロの場合はありえない
そんな理屈通りにいったら、そもそもバグなど出ないわけで。
仕様上0が入らないのならASSERT入れるんじゃないの?
Re:深刻な問題=深刻なバグ? (スコア:2)
試験に入ってすぐに発生して試験中断に・・・・・。
何てことを繰り返してくる。
#API仕様にある定数が一切入っていないヘッダ出してきたりも・・・
C言語なら (スコア:1)
ゼロ除算の結果は未定義だから、例外投げて死のうが何らかのデフォルト値を返そうがコンピューターが爆発しようが任意コードが実行されようが鼻から悪魔が出ようが仕様上は何の問題もない。チェックが不要になるわけではないが。むしろ例外が投げられると期待してチェックをサボってはいけない(実際にx86に慣れたプログラマーがARMデバイスでよく踏む罠)。
Re:C言語なら (スコア:1)
なので、アセンブラレベルで0除算か検査して例外出すように変換しています
逆に、符号付整数加算はオーバフロー例外投げることがありますので、
通常は符号なし整数加算に変換されます
アセンブラでコーディングすることを「ほぼ」前提としないMIPSならではの仕様はこのほかにもあります
Re:C言語なら (スコア:1)
まあ0番地はブート用のROMだったりRAMだったりすることも多いので、0番地アクセスを禁止されると困るわけですが。
ちなみに、わたしが普段使っているコンパイラはゼロ除算は被除数がそのまま返ります。
つまり1で割ったのと同じ結果ですね。
InifinityとかNaNとか (スコア:1)
浮動小数点数演算ではそうなってるよね
こないだ余所の会社が作ったツールを改造してたときに露骨にゼロ除算例外が出ることを期待してたコードになっててバグの原因の一つになってた
実数体でなくてよいのなら (スコア:1)
実数体ではすべての元が除算の答えとなりえるから、
デフォルトで実数体の何かの元をゼロ除算の結果として返すと
その値は元としての意味とゼロ除算としての意味を二つ重ねて持つ。
その二つを使い分ける必要があるときに分けられれば問題ないが、
結局その手間は、ゼロ除算時のエラーチェックと大差ないと思う。
マルヒ (スコア:1)
せっかくだから ㊙ を……
// やったら呆れられた
Re:マルヒ (スコア:1)
n/0を処理するとマル秘が返るんですか?
それは興味深い処理系ですね。
事務用システムの開発で簡易コンパイラやインタプリタを作って、ゼロ除算したらハイフンとか"入力なし"とか文字列を返す処理系ってのは作ったことがありますが、そういう系でしょうか。
Re:マルヒ (スコア:1)
ええ、文字列を返す処理を挟んだだけです。
ちょっとだけ頑張ったのはエラーも含め、㊙_イ、㊙_ロ、㊙_ハとナンバリングし直し文字列を返した理由と「もしかして?」をポップアップするようにした点ですね。難しいことはしていないのですが、あれこれ手間暇かけました。今でも某社某部で動いています。
除算時に制限をかけてみる…とか (スコア:1)
/\ /\ /\
(・大・ )3
___/\___________________
Jody Wisternoffこそ至高。
- Tetsuya Hiragino
Re:提案 (スコア:2)
とりあえず、0-1してみる。
Re:エラーはエラーとして現出させよ (スコア:1)
ただ、ゼロ除算のエラーとしてのクリティカルさは実務への影響に対して「異常に高い」とは思う。
これが、金融系とか数字そのものがアウトプットの用途だと困っちゃう話なんだが・・・
例えばページブレーク処理とか画面座標計算とかだと、エラーだろうが0デフォだろうが別にいいっちゃいいんだよね。
そこに至ること自体が異常で、別に対処する必要もないんだけど、ゼロ除で止まられるのもうっとおしい。
Re:エラーはエラーとして現出させよ (スコア:2, おもしろおかしい)
On Error Resume Next 最強伝説
Re:エラーはエラーとして現出させよ (スコア:1)
以前に別のストーリーでも書いたけど、テレビでタレントが「iPhoneの計算機で、ゼロで割るとエラーって表示される!」と、まるで計算結果を表示しないのが不思議で大発見のように発言しちゃって、出演者たちが感心してるような情景が視聴できる日本を見ると、やはり「エラー。ゼロで除算はできませんよ。算数を勉強し直せ」って表示すべきだと思いました。
Re:エラーはエラーとして現出させよ (スコア:1)
ていうか、独立したはずなのに未だに一方的に親子関係を保ってますねスラド。
Re:除算ってそんなに出てきますかねぇ (スコア:2)
バリバリの数値計算(数値シミュレーション)とかでなくても、平均とか分散求めるはなしはよくある。
で、起こりがちなのが、平均を求める計算で、データが1つもない時。このとき、0/0 をやってしまいがち。
また、データがひとつしか無いのに偏差値(=(データ値-平均)/標準偏差)*10+50)を求めようとして、同じく 0/0 をやってしまうとか。
また、このデータがないときの平均値というのに何がふさわしいかというと、それはそれでケースバイケース。まぁ、数学的に不定値だし。
Re:出なかった (スコア:1)
それ、多分 / 演算子を使ってるからですよ。/ 演算子は浮動小数点数除算で、浮動小数点数演算はIEEE 754に従いますから。
VBでの整数除算は \ 演算子を使い、こちらではDevideByZeroExceptionが発生します。