プログラムはなぜ小数の計算をミスるのか?

YouTube で視聴

概要

自作電卓で 0.6-0.20.3999997 のように表示される現象から、プログラムにおける浮動小数点演算の誤差を説明する回。10進数ではきれいに見える 0.1 も、コンピューター内部の2進数では循環小数になり、近似値として扱われる。対策としてDecimal型的な10進演算を紹介し、後半ではCookie、IPアドレス、広告追跡、VPNの話へ展開する。技術的な小ネタと視聴者相談をつなげ、日常の違和感から計算機とネット広告の仕組みを読み解く。

要点

  • 0.6-0.20.4 にならないのは、10進小数を2進数で正確に表せない場合があるため。
  • 0.1 は10進数では有限小数だが、2進数では 0.00110011... のような循環小数になる。
  • 浮動小数点型は実数を近似値として持つため、近似値同士の演算で微小なズレが出る。
  • Decimal型は値を整数部分と小数点位置の情報に分け、10進数として扱うことで金額計算などに向く。
  • Cookieは基本的に端末・ブラウザー単位で保存され、同じWi-Fiの家族端末へ直接共有されるわけではない。
  • 同一回線ではIPアドレスが共通になるため、広告事業者がIP単位で傾向を推定する可能性は残る。
  • シークレットモードはCookieや履歴の残り方を変えるが、IPアドレスを隠す用途にはならない。

構造化サマリ

小数計算がずれる理由

導入では、自作電卓で 0.6-0.2 を計算すると 0.3999997 のような値が出るという投稿を取り上げる。見た目には単純な引き算だが、プログラム内部では10進数の小数をそのまま持っているわけではない。

コンピューターは基本的に0と1の2進数で数を表現する。10進数の 0.1 は人間には切りのよい小数に見えるが、2進数では循環小数になり、有限のビット数では正確に保持できない。0.60.2 も近似値として保存されるため、演算結果にもわずかな誤差が現れる。

浮動小数点とDecimal型

通常の浮動小数点型は、広い範囲の数を効率よく扱える一方で、すべての10進小数を正確に表せるわけではない。科学技術計算やグラフィックスでは十分な場面も多いが、金額や会計のように1円単位のズレが問題になる領域では注意が必要となる。

対策として、動画ではDecimal型の考え方を説明する。たとえば 0.6 を2進小数へ変換するのではなく、6 という整数と「小数点を1桁落とす」という桁情報を分けて保持する。整数演算と小数点位置の管理を組み合わせることで、10進数として期待される結果を保ちやすくなる。

牛角ドメインの謎

途中から話題は、牛角の公式ドメインが gyukaku.ne.jp であることへの疑問へ移る。通常 ne.jp はネットワークサービス事業者向けの属性型JPドメインとして知られるため、飲食チェーンの公式サイトに使われている点が不思議な例として扱われる。

WHOISを確認すると1999年に取得されたことは分かるが、なぜこのドメインが選ばれたのかは動画内では解決しない。問い合わせ予定として保留され、プログラムの小数誤差からインターネットの制度的な小ネタへと脱線する構成になっている。

Cookie、IPアドレス、広告追跡

後半では、同じWi-Fiを使う母親のスマホに性的広告が出るのは自分の閲覧履歴のせいか、という視聴者相談を扱う。Cookieは端末とブラウザーに保存されるため、家族の端末へ検索履歴やCookieがそのまま共有されるわけではない。

一方で、同じ家庭回線からアクセスしていれば、外部サービス側から見えるIPアドレスが同じになる場合がある。そのため、広告事業者がIPアドレス単位で関心傾向を推定する可能性はゼロではない。ただし動画では、実際にはAmazonなど多くのサービスがアカウント単位の推薦を重視しており、IPアドレスだけで露骨な広告を出す例は多くないだろうと見る。

VPN広告と締め

シークレットモードはブラウザーに履歴やCookieを残しにくくする機能だが、アクセス元IPアドレスを隠す機能ではない。もしIPアドレス由来の広告推定を避けたいなら、シークレットモードだけでは不十分となる。

ここからSurfsharkのVPN広告へつなげ、VPNサーバーを経由すると相手に見えるIPアドレスがVPN側のものになると説明する。公共Wi-Fi利用時の安全性やDDoS攻撃リスクの低減にも触れ、最後は番組へのお便り募集で締める。

登場エンティティ・コンセプト

  • yurucom — プログラミングやITの疑問を会話形式で扱うYouTubeチャンネル。
  • surfshark — 動画終盤で紹介されるVPNサービス。
  • floating-point-arithmetic — 2進数による近似表現を使うため、小数計算に微小な誤差が出る計算方式。
  • decimal-arithmetic — 10進小数を整数と桁情報として扱い、金額計算などで誤差を避ける考え方。
  • ip-address-ad-tracking — 同一回線のIPアドレスを手がかりに広告傾向を推定する可能性を扱う論点。

印象的な引用

0.1って俺たちが10進数の住人だからキリいいと思ってるだけで、2進数の住人からするとめっちゃキリ悪いっす。

シークレット使っても結局同じIPアドレスからアクセスしちゃってるから。