59 ポイント 投稿者 GN⁺ 2025-02-17 | 12件のコメント | WhatsAppで共有

「電卓アプリ? 誰でも作れるんでしょ」→ 実はそうではない

  • 電卓は数式の結果を正確に表示しなければならず、思ったよりはるかに難しい
  • iOSの電卓では (10^100) + 1 − (10^100)0 と誤って計算してしまう
  • しかしAndroidは正しく 1 と表示するが、これをどう実現したのかは本当にとんでもない話

GoogleとHans-J. Boehm

  • Googleは著名なプログラマー Hans-J. Boehm を雇用した
  • Boehm は C++ の共有変数セマンティクスを定義した専門家
  • しかし彼に与えられた任務は、予想外にも電卓アプリの開発だった

浮動小数点の問題

  • 浮動小数点数では 0.310^100 のような値を正確に表現できない
  • つまり、浮動小数点ベースの電卓は信頼できない
  • 正確な計算のためには別のアプローチが必要

Bignumを使った解決策

  • 整数計算の問題は Bignum(任意精度整数)を使えば解決できる
  • Bignum はメモリ容量に応じて動的に拡張される整数型
  • (10^100) + 1 - (10^100) の問題は Bignum を使えば解決する
  • しかし分数演算は解決されない
広告

分数と代数的数

  • 分数(3/4 のような値)は Bignum を使って分子と分母を保存すれば解決できる
  • しかし円周率(π)や平方根(√2)のような無理数は表現できない
  • Boehm は多項式ベースの表現を試みた
    • 例: √2x² - 2 = 0 という方程式で表現できる
    • しかし π はこの方式でも表現できない

構成的実数(Constructive Real Numbers)

  • Boehm は「再帰的実数演算(RRA)」の概念を探究した
  • ユーザーが望む精度を入力すると、その精度内で値を計算する方式
  • 例: π を 0.01 の誤差内で表現すると 3.14 を返す
  • しかしこの方式では正確な比較が難しくなる

正確な0を表現する問題

  • RRA 方式では 1 - 10 ではなく 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件のコメント

 
street62 2025-02-20

余談ですが、AIのneoが「そうじゃん」と訳したのが興味深いですね。原文は "Anyone could make that" で、いたずらっぽいニュアンスはないのに(笑)、ぴったりですね。

 
gurugio 2025-02-19

学部生のとき、8086ボードを手ではんだ付けして作り、数字キーパッドとテキストLCDをつないで、8086アセンブリで電卓(四則演算だけをするもの)まで作る授業がありました。
ボードを作って、キーパッドとLCDまで接続して動かすところまではできましたが、電卓は作れませんでした。
そのときは自分にはソフトウェアの才能がないのだと思ってハードウェアエンジニアとして就職したのですが、どういうわけか今はソフトウェア開発をしています。
電卓、本当に難しかったです。

 
yunsub2 2025-02-19

「geojana」→「geojanha」です。😃

 
carnoxen 2025-02-18

電卓アプリ? そんなの誰でも作れるじゃないですか?

でも浮動小数点の調整は面倒くさそうですね?wwww

 
tribela 2025-02-18

電卓アプリですか? そんなの誰でも作れるじゃないですか?

電卓といえば、私はWindowsの標準電卓を思い出します。2+2*2 を計算すると、6ではなく8になります。わざとこう作ってある気もしますが、まったく理解できません。以前、カクテルに含まれるアルコール量を計算したら、アルコールが飲み物の総量より多くなってしまって、困惑したことがあるんです。

 
khrad 2025-02-19

演算子を押すたびに前の式がその場で計算される一般的な電卓の動作方式に従ったものですが、関数電卓しか使ったことがないのですか?

 
ned0909 2025-02-18

完全に同感です。サーバーがいらないから楽だと思って電卓から始めたのに、次々と出てくる計算ミスやバグを潰すのに本当に苦労しました

 
aer0700 2025-02-17

「電卓アプリ? そんなの誰でも作れるでしょ?」→ 事実ではない
これ、応用できるところが無限にありそうですね(笑)

「Python? めっちゃ簡単でしょ」→ 事実ではない

 
tsboard 2025-02-17

私も見ながら同じことを思いました。www

「JavaScript? 余裕でしょ」→ 実際はそうではない

 
joyfui 2025-02-17

"(10^100)+1−(10^100)"
おお、本当にiPhoneの計算機は0、Androidの計算機は1と表示されますね。
でも実際にGoogleで検索すると0と出るんですね……

 
GN⁺ 2025-02-17
Hacker Newsの意見
  • 興味深い話だ。数を表現するより強力な方法は、連分数で表現することだ。連分数は実数と有理数を効率的に表現できる
    • 面白いことに、それほど古くない数学の教科書によれば、連分数の加算/乗算アルゴリズムは存在しない可能性が高いという。しかし1972年にBill Gosperが、連分数は算術に完全に適していることを証明した
    • 私は reals というPythonライブラリを開発中だ。このライブラリは DecimalFraction 型を置き換えられるように設計されている。Bill Gosperの技法を使って連分数を操作する
  • リンクが短縮されていてクリックできないのは残念だ。ここに論文への実際のリンクがある
  • タイトルを読んだ瞬間に笑ってしまった。IEEE 754は最悪だが、それでも他のすべてよりはましだ。例を見た瞬間、Kahan summationか完全なコンピュータ代数システムの話だと思った。Recursive Real Arithmeticは聞いたことがなかった
    • 初期のC++ヒーローの1人について洞察を得られた。一見シンプルなものがどれほど深いかを思い出させてくれる
  • NYCの地下鉄運賃は$2.90だ。iOSでPCalcを使ってMetroCardの残額を計算したところ、0ではなく -8.881784197E-16 になった。Appleの計算機を使うとこうはならない
    • 開発者に問い合わせたところ、Appleは独自の数学ライブラリを使っており、これを置き換える別のライブラリを探す必要があると返答された
  • ほとんどの人は完全な計算機アプリを作っていない。TI-89のような完全な計算機という意味だ
    • AndroidでTI-89計算機エミュレータを使っている。Androidアプリの半分の機能もなく、しかもあまりうまく動かない
  • RRAに切り替えることの欠点は、ユーザー体験だけではない。結果が 0.0000000... のとき、計算機はその数の逆数を計算できるかどうか判断できない
    • たとえば、1/(atan(1/5)-atan(1/239)-pi/4) は「計算できない」と表示する。1/(atan(1/5)-atan(1/239)-pi/4+10^(-100000)) を試しても、やはり「計算できない」と表示する
  • ほとんどすべての数はIEEE浮動小数点では表現できない。ランダムな数が理論的に記述不可能である確率は約100%かもしれない
    • いくつかの問題はbignumを使えば避けられる。一瞬の実存的不安が和らいだ
  • TI-92のような高機能TI計算機がこのシステムを使っていたか知っている人はいる? 「有理数」モードがあって、RRAを使っていた可能性がある
  • 「recursive real arithmetic」(RRA)の使い方は、Conal Elliotとの素晴らしい議論を思い出させる。物事を離散的に表現することから連続的に表現することへ移る話をしていた
    • たとえば、以前はフォントをピクセルの塊として表現していたが、今では線/ベクトルとして認識される。コンピュータサイエンスは最新の商用ツールを学ぶことだけでなく、真実を追求するものであるべきだ
  • Android Open Source Projectの計算機ソースコードをいじってみた。GoogleはこれをGoogle Play Servicesへ移したが、古いソースは今でも利用できる
    • いくつか実際の問題を解決しており、ライブラリで使えるようになってほしい。前の記事ではいくつかのライブラリについて議論があった