はてなキーワード: 丸め誤差とは
なんか今頃になって小数の丸め誤差の話が盛り上がってるんだけど
そもそもできる限り小数を使わないっていうのはプログラミングの基本でしょ
割と適当でいいものについては小数(float)を使うけど厳密なところは整数(integer)にしましょうって最初に習わないの?
例えば日本だとあんまり馴染みが無いけれど海外だと金額はだいたいが小数で扱われてて
$5.3-$2.8 みたいな計算をするんだけど
ところがそもそもドルじゃなくてセントにしてしまえば何も問題は起きない
システムで扱う単位をセントにしておいて表示するときにドルにすればいいだけ
他にも長さを入れるときにメートルで入れると小数を使わないといけなくなるからミリメートルで入れる、とか
時間も秒単位だと誤差がでるからミリ秒とかマイクロ秒で入れる、とか
精度が求められてないとかそもそも精度に意味が無い場合は小数使えばよくて
まぁUnixtimeがfloatで入ってても問題無い場面はあるとは思うけどね
DecimalだとかBigDecimalだとか議論する前に本当に小数計算が必要なのかよく考えて欲しい
暗黙的にJSTとして時間を使ったせいでUTCで作った場所で盛大にバグる
応急処置でバグったところを+9とかやってしまうと、それ以降に逆に誰も気付かずに更に影響範囲が拡がったりする
海外展開しようとしたときにバグに気付くがどうしようもなくなって途方にくれて海外だけは別アプリになったりする
UNIXTIMEを使えば楽なんだけれど、そうすると生データぱっと見で時間を判別できないので困ることも多い
素直にUTCでISO8601が良い
とりあえずUTF-8にしとけば大丈夫、ってことで実装を進めた結果、Mac/Winでハマる
他にもBOMでハマったりして、むしろSJISの方が良かったんじゃ無いか、とか言い出す
DBが統一的になっている場合はまだ後からどうにかできるが、変なところでキャッシュされてたりすると凄い困ることになる
MySQLなりPostgreSQLなりでUTF-8を正しく扱う方法はいろんな記事があるのでちゃんと読んでおけば問題無い
とかよく分からないことを言い出して価格を浮動小数にしてしまう
確かに米国なら$2.43みたいな感じで価格を使ったりするし、むしろ小数点以下が無い通貨の方が珍しいのだけれど
丸め誤差を考えないで作ってしまってバグが見つかりめちゃくちゃ揉める
数学的な手法を使って実在しない人物やイラストを生成しているといた旨の説明がされるが、
本当に違っていると証明したのを見たことがなく、本当か?という疑問がある。
(元のデータ量が膨大なので類似画像の証明が困難なのは承知している)
本当に「実在しない人物」が生成されるのであれば、有名人の名前を入れても再現されないはずだが、
エマ・ワトソン、トランプ、イーロン・マスクなどは大量に作られている。
例えばdiffusionモデルだと、元の画像全体に対してノイズを加えていったもので学習させている。
これだけ見ると、「学習元画像をどれだけ再現できるか」、というのは学習しているが、
学習時の指標としてエラー率を下げるというのもあるが、こちらも「学習元画像をどれだけ再現できるか」だろう。
「学習元と違う画像を生成」しているが、人の目で見た時に全体としてバランスが取れているという指標ではない。
ではないだろうか。
だが、より詳細な画像を出そうとした場合、パラメータ数や演算精度を上げていった場合、
海外で機械学習系の博士号まで取ったけど、(知ってて損することもないけど)大半の人間にはこんな詳細知識いらんよなって感じだわ
中身わかってなくてもpythonパッケージ類に投げれば全てが解決されるしそういう人も多い 今時丸め誤差とか気にせんでも動くことは多いし、それで用に足るならこだわるだけ時間の無駄
大規模システムとかでそれやったらしばかれて仕方ないけどな
俺は手法でいっぱい論文書いてるけど、それを効率的に実装できるかとか商品にまでもっていけるかってのは別の話で、そのあたりは別のプロとか実働部隊のお仕事って割り切ってる
ここまではよくわかる。それで物理学と数学的なカオス理論を押す連中が間違っていると思うのが、
二度目の入力の際に手間を惜しみ、初期値の僅かな違いは最終的な計算結果に与える影響もまた小さいだろうと考えて、小数のある桁以降の入力を省いたところ、
ここ。ここが諸悪の根源だ。まず計算機科学の連中が大学に入って最初に引っかかるミスに大御所がひっかっている。たとえば、0.4 - 0.3 は計算機科学では 0.1 じゃない。それは十進法から二進法に変換するという計算機の特性を理解してない人がやるミスだ。嘘だと思ったら、0.4 - 0.3 == 0.1 と C なり Ruby なり Python なり Java なり Haskell なりでやってくれ。ちなみに JavaScript なら 0.4 - 0.3 === 0.1、Lisp族の Clojure は (== (- 0.4 0.3) 0.1)、PHP はちょっと自信がないので省かせてもらう...。浮動演算ユニットがついているプロセッサで IEEE 754 の類をサポートしているなら「偽」となるはずだ。ここでは「桁あふれ」「丸め誤差」なんかは説明しないが、計算機で小数を扱うのは注意が必要ってことだ。閑話休題、つまり計算機で数学や物理学が実数のように小数点を扱うなら 3.0 と 3.1と 3.14 は別物として扱う必要があって、カオス理論の創始者であるローレンツは「有史に残る」ミスを犯した。
結果が大きく異なった。
これは金融界隈のエンジニアたちにとっては、コンピュータが現れてからは悪夢のような形で襲っていて、ゴースト・イン・ザ・シェルの題材にすらなっている「既知の未知」という類のエラーだ。はっきりいうと、大御所にこんなことを言うことは憚れるが、エンジニアだと3年目以降だとしないミスを MIT のエリートがやっているという、なんというか「そりゃ、そうなるだろ」的なミスをしでかした結果なんだよ。例えば、古典物理学だと有効数字のひとつ下の数値は切り上げて四捨五入するというのは教科書的には正しい。だがね、計算機科学だと小数点の扱いは事故の元なんだよ。具体例を出すと「Ruby で円周率を100回掛け合わせる、Ππ(パイパイ、n=100)みたいなことをする。
puts [3.0, 3.1, 3.14].map{|i| 100.times.reduce(i) {|j, k| j *= k + 1}} # 2.7997864633183236e+158 # 2.893112678762268e+158 # 2.930443164939848e+158
もう一度、特に高校の物理をやった人は考えてほしい。数値を切り捨てしないだけで、これだけの差が生じるのだ。そりゃ、ローレンツ大先生も驚くわな。現実世界では起きないような気がするのはなぜか?、と思うじゃん。そこで、わたしはこう思うわけですよ、
とね。だからこそ、
というものを科学する学問があって良いのじゃないかと。つまり、
なのではないかと。