電卓アプリ? 誰でも作れるんでしょ?
(chadnauseam.com)「電卓アプリ? 誰でも作れるんでしょ」→ 実はそうではない
- 電卓は数式の結果を正確に表示しなければならず、思ったよりはるかに難しい
- iOSの電卓では
(10^100) + 1 − (10^100)を0と誤って計算してしまう - しかしAndroidは正しく
1と表示するが、これをどう実現したのかは本当にとんでもない話
GoogleとHans-J. Boehm
- Googleは著名なプログラマー Hans-J. Boehm を雇用した
- Boehm は C++ の共有変数セマンティクスを定義した専門家
- しかし彼に与えられた任務は、予想外にも電卓アプリの開発だった
浮動小数点の問題
- 浮動小数点数では
0.3や10^100のような値を正確に表現できない - つまり、浮動小数点ベースの電卓は信頼できない
- 正確な計算のためには別のアプローチが必要
Bignumを使った解決策
- 整数計算の問題は Bignum(任意精度整数)を使えば解決できる
- Bignum はメモリ容量に応じて動的に拡張される整数型
(10^100) + 1 - (10^100)の問題は Bignum を使えば解決する- しかし分数演算は解決されない
分数と代数的数
- 分数(
3/4のような値)は Bignum を使って分子と分母を保存すれば解決できる - しかし円周率(π)や平方根(√2)のような無理数は表現できない
- Boehm は多項式ベースの表現を試みた
- 例:
√2はx² - 2 = 0という方程式で表現できる - しかし π はこの方式でも表現できない
- 例:
構成的実数(Constructive Real Numbers)
- Boehm は「再帰的実数演算(RRA)」の概念を探究した
- ユーザーが望む精度を入力すると、その精度内で値を計算する方式
- 例: π を
0.01の誤差内で表現すると3.14を返す - しかしこの方式では正確な比較が難しくなる
正確な0を表現する問題
- RRA 方式では
1 - 1を0ではなく0.0000000001と表現してしまうことがある - これはユーザー体験(UX)の面で問題になる
- Boehm はほかの研究者たちと協力して解決策を探し始めた
Richardson-Fitchアルゴリズム
- 1994年、Dan Richardson と John Fitch は特定の演算内での数値比較問題を解決した
- しかしこのアルゴリズムは遅すぎて、現実的には利用不可能だった
- たとえば
1 ≠ 1 - e^(-e^1000)を判定するには、宇宙の原子数より多い演算が必要になる
RRAと有理数演算の組み合わせ
- Boehm は RRA と有理数演算の長所を組み合わせるアイデアを思いついた
- 単純な演算(例:
6 × 9または8 / 3)には有理数演算を使う - 無理数が含まれるときだけ RRA を使う
- 結果として、数を 有理数 × 実数 の形で表現する
記号的表現(Symbolic Representation)
- π や √2 のような特別な数には、RRA の代わりに記号的表現を使う
- 例: π は「π」という記号で保存し、必要なときだけ数値に変換する
- 四則演算だけでなく、三角関数(sin, cos, tan)、対数、指数関数にも記号的表現を活用する
最終的な解決策
- すべての数は 有理数 × 実数(記号的表現または RRA) の形で保存する
- 可能な場合は有理数演算を使って正確さを維持する
- 記号的表現を最大限活用して RRA 演算を最小化する
- 結果として、速度と正確さのバランスを取った完璧な電卓システムが完成した
結論
- Boehm と彼のチームが作った Android 電卓は単純なプログラムではない
- 正確な結果を提供しつつ、高速で効率的なアルゴリズムを適用している
- 「ただの電卓アプリ」ではなく、数学的に精巧なシステムである
「次にAndroid電卓を使うときは、この努力を思い出してみよう!」
12件のコメント
余談ですが、AIのneoが「そうじゃん」と訳したのが興味深いですね。原文は "Anyone could make that" で、いたずらっぽいニュアンスはないのに(笑)、ぴったりですね。
学部生のとき、8086ボードを手ではんだ付けして作り、数字キーパッドとテキストLCDをつないで、8086アセンブリで電卓(四則演算だけをするもの)まで作る授業がありました。
ボードを作って、キーパッドとLCDまで接続して動かすところまではできましたが、電卓は作れませんでした。
そのときは自分にはソフトウェアの才能がないのだと思ってハードウェアエンジニアとして就職したのですが、どういうわけか今はソフトウェア開発をしています。
電卓、本当に難しかったです。
「geojana」→「geojanha」です。😃
電卓アプリ? そんなの誰でも作れるじゃないですか?
でも浮動小数点の調整は面倒くさそうですね?wwww
電卓アプリですか? そんなの誰でも作れるじゃないですか?
電卓といえば、私はWindowsの標準電卓を思い出します。
2+2*2を計算すると、6ではなく8になります。わざとこう作ってある気もしますが、まったく理解できません。以前、カクテルに含まれるアルコール量を計算したら、アルコールが飲み物の総量より多くなってしまって、困惑したことがあるんです。演算子を押すたびに前の式がその場で計算される一般的な電卓の動作方式に従ったものですが、関数電卓しか使ったことがないのですか?
完全に同感です。サーバーがいらないから楽だと思って電卓から始めたのに、次々と出てくる計算ミスやバグを潰すのに本当に苦労しました
ソースコード内の実装概要
ソースコード内の計算機演算ロジックの説明
整数処理コード
実数処理コード
「電卓アプリ? そんなの誰でも作れるでしょ?」→ 事実ではない
これ、応用できるところが無限にありそうですね(笑)
「Python? めっちゃ簡単でしょ」→ 事実ではない
私も見ながら同じことを思いました。www
「JavaScript? 余裕でしょ」→ 実際はそうではない
"(10^100)+1−(10^100)"おお、本当にiPhoneの計算機は0、Androidの計算機は1と表示されますね。
でも実際にGoogleで検索すると0と出るんですね……
Hacker Newsの意見
realsというPythonライブラリを開発中だ。このライブラリはDecimalやFraction型を置き換えられるように設計されている。Bill Gosperの技法を使って連分数を操作する1/(atan(1/5)-atan(1/239)-pi/4)は「計算できない」と表示する。1/(atan(1/5)-atan(1/239)-pi/4+10^(-100000))を試しても、やはり「計算できない」と表示する