みんなのオブザイヤーオブザイヤーを募集中!今年のツイート今年のうちにまとめよう!
152
mはげ @Tw_Mhage
30年前の名著「数値計算の常識」を読んでたらBASICで0.01を10000回足したら100.003になるとか書いてあった。まあ昔のPCなんてそんなものかなと思いながら、Visual Studio 2017で試してみたら同じ結果だったw pic.twitter.com/HBwJhlhZjc
 拡大
 拡大
Eijiro Sumii @esumii
@Tw_Mhage @masanork ご参考まで、添付画像のような例もあります。JavaScriptではなくほとんどの言語でも同様です。浮動小数点演算はもう長らく変わっていないか、むしろGPU等では倍精度ではなく単精度に落ちているケースも多いと思います。唐突に失礼しました。 pic.twitter.com/JWHW1p616V
 拡大
mはげ @Tw_Mhage
@esumii @masanork ありがとうございます。コンピュータの処理速度は上がっても、上がってない性能もあるのですね。面白いですね。
TokusiN @toku51n
@Tw_Mhage @esumii @masanork 精度が必要なら100桁でも10000桁でも好きな精度で計算できますが、普通はそんなに必要ないので精度を上げていません。上がっていないのではなく、上げていないのです。
雷更新世 @pleist
@toku51n @Tw_Mhage 必要ないというより、いくら精度を上げても違う進数で微量のズレが出ることの解決にはならないですからね。
TokusiN @toku51n
@pleist @Tw_Mhage それを解決するために有理数型を使うこともあります。有理数の厳密な計算をしたいとき以外はまず使いませんが。
雷更新世 @pleist
@toku51n @Tw_Mhage そうなりますよね。そのへんの型を高速に扱える機構がCPUに組み込まれればまだしも。まあ需要がさほど無いでしょうし、結局いつまでも「小数は誤差を理解して使うのが常識」に落ち着くんでしょうね。
こばさん @wakwak_koba
@pleist @toku51n @Tw_Mhage 例示の通り C# を使うような用途だったらむしろ逆で、デフォルトを decimal 型としつつ、どうしても速度が必要、有効桁数がもっと必要、という場合だけ double 型を検討する、という風かなと思います。。
雷更新世 @pleist
@wakwak_koba 10進数に限るならdecimalもよいですね。
耕士 @ysdkz
@Tw_Mhage iPadのPyonkeeでやってみました。 pic.twitter.com/EyrIsPIGcU
 拡大
耕士 @ysdkz
@Tw_Mhage 浮動小数点表現のせいで不正確になるなら、常に多めか常に少なめかのどちらかになる気がするのですが、気持ち悪いことに足す回数で、多めになったり、少なめになったりします。画像は500回足した結果で、正確な値より少なめです。表示の際に下の桁を四捨五入とかしてるんでしょうか? pic.twitter.com/zFIKRjd2iP
 拡大
mはげ @Tw_Mhage
@ysdkz 誤差の原因は2つです。実は2つ目の方が支配的です。 また2つめは多め少な目どちらも起こりえます。 1. 10進数を2進数の32bit浮動小数点に変換した際の丸め誤差(表現誤差) 2. 大きい数(今までの合計)と小さい数(これから足す数)の足し算時の桁落ち誤差
耕士 @ysdkz
@Tw_Mhage そうですね。学生の頃、数値計算の授業で、大きい数と小さい数の足し算は精度が落ちるって習ったのを思い出しました。
seafurry @seafurry
@Tw_Mhage @masanork 浮動小数点の仕様が昔と変わっていないって事か。
tarosuke @tarosukenet
@Tw_Mhage 十進で言えば例えば1/3 * 3000とかを限られた桁数でやるようなもん。例えば三桁なら1/3は0.333で、これに3000かけても999になる。1000にはならない。 一般化するとn進で1/mを表現するときにはmの素因数が全てnの素因数に含まれてないと有限桁では正しく表現できない。二進じゃ素因数は2しかない(ry
海王星スープ @miitsuEX
@Tw_Mhage @karaage0703 この本もってる・・・。ダンボールの中にあるはず。 あの、ご迷惑でなければ何ページに載っているか教えていただけますでしょうか。
mはげ @Tw_Mhage
@miitsuEX @karaage0703 2ページ目です。まだ読み始めたばっかりです。
海王星スープ @miitsuEX
@Tw_Mhage @karaage0703 返信&回答ありがとうございます。 参考になります。
@picocastle
@Tw_Mhage @hmatsumu 興味が湧いて64bitコードにしてdoubleでもやってみましたが、やはりしっかり計算出来ないんですね。 勉強になりました。 pic.twitter.com/9lf96S2Cu5
 拡大
lunablanca @lun_blanc
@picocastle @Tw_Mhage @hmatsumu 横からすみませんが明朝体でコーディングしてるの初めて見ました…!

コメント

素のしめ釜 @n0sime 27日前
播磨の某射光施設のXPS装置の生データ,E_kinの値が同じような振る舞いをしているのだが,もしかして。。。
Haruka Oh! @sylphied_ 27日前
そりゃIEEEの規定が変わってない以上同じにならないとおかしいよね。
F414-GE-400 @F414_GE_400 27日前
この辺のことをちゃんと理解できていないのでいまだに電卓やエクセルで計算するのが怖い
まさご叔父さん @masago53 26日前
数値の型を勉強すると必ずついて回るやつ
いぬだわん @InuWang 26日前
汎用機CPU(IBM系)は10進固定小数点演算の命令持ってますね。 PACK/UNPKで10進(BCD)←→文字コード(E”BCD”IC)変換も楽ちん。
nekosencho @Neko_Sencho 26日前
昔のというけど、昔の、カシオのFP系はBCD(二進化十進数)演算のBASIC使ってたので10進の小数でも誤差でないぞ。 そのかわりクソ遅くて当時のゲームとかしたいユーザからは嫌われたけどw
nekosencho @Neko_Sencho 26日前
Neko_Sencho もちろん、パソコンとしてクソ遅いのではなく、二進数しか計算できないCPU(Z80)で、わざわざ10進数扱いにして計算する手間を食って遅いのです。 CPUを直接動かしてやれば、当時のパソコンとしては標準的な速度は出せました。
Tadashi @tadashifx 26日前
こういう話に尾ひれがついて「PC(Exccel)は信用できない! 全部電卓で計算して!」という人が出てくるのが世の中の恐ろしいところ。
きゃっつ(Kats)⊿12/13がなくり武道館 @grayengineer 26日前
内部的に2進数だからというのが理由ですが、むかしカシオ計算機が出していたコンピュータは整数演算を10進で扱っていたのでこの問題は生じませんでした。ただしその分演算速度がかなり犠牲になっていました。 現在でもDecimal型(10進扱い型)を使えば回避できます。
桜花ゲートウェイ@多摩丙丁督 @Sakura87_net 26日前
じゃけん.NetならDecimal型が生まれたん。
永遠の初見さん @Eternal_NewMan 26日前
コンピュータの世界では桁落ちという概念だが、物理化学だと有効数字に変貌する。
maci @ma_ci6 26日前
これどうしてこうなるのか、なんで今もこのままなのか教えてください……
ぱんどら @kopandacco 26日前
MSXは1になるんではないか? 手元にないので試せないけど
🍤💨の沼海老 @mtoaki 26日前
ma_ci6 二進数で小数点以下を表すと0101は1/4+1/16、1100は1/2+1/4みたいな感じになるから。だったと思う。
east @1963_east 26日前
ma_ci6 雑に説明すると、コンピュータ内では10進数ではなく、2進数で数字をカウントしている。つまり、10進数の0.5や0.25は2進数で『0.1(2)』『0.01(2)』として表せるが、10進数の0.1は『0.00011001100...(2)』と循環小数になってしまう。もちろん無限に桁を使って計算なんてできないので、どっかで打ち切って近似で計算する必要があるので、微々たる計算の誤差が出る。
いぬだわん @InuWang 26日前
ma_ci6 このサイトの計算機が親切な解説付き。 https://note.cman.jp/convert/bit/ なんで今も浮動小数点を使い続けてるかというと計算が速いしメモリ消費量も少ない。 金額計算とか誤差が出ては不味いのは必要な精度(整数部桁数、少数部桁数)の10進数ベース型で計算する。 何使っても1/3とか循環小数になると駄目なので精度をどこまで持つかは要件次第。
きさらぎ♒ @bubassmc 26日前
1963_east 質問者じゃないですが、分かりやすくて理解できました。 ありがとうございます。
山吹色のかすてーら @sir_manmos 26日前
10進数でも、1/3を「有限桁で」少数化してから、3倍すると1にならないよね。そういうこと。
doipo @doipo 26日前
性能が上がったら精度も上がると思ってるツイート興味深いねw
Aki @Yy7_f 26日前
Excelで0.01を10,000回足すと100になりますよ。まあほかの浮動小数点数の計算で誤差が出ることはあるのだけど。 それより、-1^2=1と解釈するのは表計算では一般的なのかな。VBAでは-1なんだけど。一度うっかりして困ったことになった。
yasu (HIRATA Yasuyuki)@アスカネット @hirayasu 26日前
Yy7_f VBA (VBも?) の優先順位が特殊なだけかと。(Excelの表計算機能では、符号反転の-が指数演算子^よりも優先) https://docs.microsoft.com/ja-jp/office/vba/Language/Reference/User-Interface-Help/operator-precedence
Aki @Yy7_f 26日前
ごめん、100にならなかった。Excel 2016で100.000000000014になるね。
Aki @Yy7_f 26日前
hirayasu うーん、仕様というのはわかるんだけど、一般的な数式のルールと異なっているのに違和感がある。 例えば、金利計算なんかでexp(-rT)みたいな形がよく出てくるのだけど、=EXP(-A1^B1)みたいに書くと望んだ結果が得られないので、=EXP(-(A1^B1))って書かなくちゃいけない。
oshow2001 @oshow2001 26日前
2進ではなく10進で計算するBASICってのがあったなぁ。その分、計算はくそ遅い。
sk @sk_exe 26日前
Excelのワークシート上で計算する場合、内部処理上は倍精度浮動小数点型(Double)の数値データがセルに格納されている形になっているので、極小とはいえ演算誤差は生じる。合計が100.003になるのは、単精度浮動小数点型(Single)の0.01を10000回足す処理を実行した場合。(データ型による演算結果の違いについては、まとめでも言及されている)
ねるにあ†Ridill @nelnia 26日前
デジタルの限界でもあり、面白いところでもあるね。一般生活では小数点以下2桁くらいで十分なんだけど、膨大なデータ量や数値を扱う宇宙分野や物理の世界ではいろいろ大変そうだわ
oshow2001 @oshow2001 26日前
だから、最終的に精度(桁数)から、誤差がその精度より小さくなるように、変数の型を選択するし、計算式も誤差が増えないように順番を変えたりする。
addwisteria @futamori 26日前
量子コンピューターはこの当たりの精度問題引きずるのかな
mmotopapa @mmotopapa 26日前
コンパイラの不具合じゃないのか!ってクレーム付けてくる人が意外と多いんですよ(笑)
phantive @phantive 26日前
同じことをやれば同じになる。 性能も容量も格段にアップしてるんだから、倍精度でも十進でも好きに使えば、という話。
trycatch777 @trycatch777 26日前
まあ適切な型と計算方法を選択しましょう、というよくある話ですよね。
kartis56 @kartis56 26日前
COBOLやFORTRANは型定義ちゃんとあって普通に使えるし早い
kartis56 @kartis56 26日前
エクセルで100になるのは表示上の有効精度3桁で下が切れてるだけでは? 少なくともオンライン版でΣ0.01 が5000行で49.99だった。書式指定はデフォルトなのでまとめと同じ
Daregada @daichi14657 26日前
FP-1000/1100ユーザーホイホイになっとるな
kusano @t_kusano 26日前
エクセルが信用できないのはこういう話に尾ひれがついたせいじゃなくて、コピペミスとかで途中の式が壊れてるのに気づかない可能性があるからじゃないの?
yasu (HIRATA Yasuyuki)@アスカネット @hirayasu 26日前
Yy7_f それを言ったら、^ を使うのが一般的な数式と違うので。;-p (HAL/Sみたいにべき乗をそのまま表現できるプログラミング言語が必要?)
VRAM01K @VRAM01K 26日前
ExcelVBAならCurrency(通貨型)使うと誤差出ないはず
生きたい @dtdknopmh 26日前
うーん、最新のマシンならとにかく性能がいい(おおざっぱ)と思ってるやつかな。 プログラムを勉強したことない人が、そういう先入観を持つのは、割とありがちな事なんだろうな。
Aki @Yy7_f 26日前
hirayasu その理屈で言うと、VBAとの違いを説明できないですね。あとカッコで容易に対応できるのに別の道具を持ち出す必要もない。
east @1963_east 26日前
nelnia よくフィクションで聞くカオス理論ってのがまさにそれだったりするよ。数値計算でやると誤差がとんでもないことになって、まともな答えが得られないってやつ。
kartis56 @kartis56 26日前
1963_east カオス理論は誤差の話ではなくて、3体問題は答えが出ないって話
kartis56 @kartis56 26日前
[c5663154] エクセルなら通貨型があるのでそれを使えばいい
愛国者?pgr @aikokuwww 26日前
昔は、コンピュータのことを勉強する時は2進数での小数の扱いについては真っ先に勉強するもんだったし、誤差を小さくするように計算順序を変えることとかも基本だったのだけど、今みたいにコンピュータが一般的になるとむしろ習わなくなる話になってるんでしょうね。
むう @nyal1999 26日前
mmotopapa そういやMSC6でchar→intの型変換込みで*10したら9倍の値返してきたという不具合が…
じゃこうねこ @Jakoneko2 26日前
まさかこんなところでFP-1100ネタが出てくるとは。
mikunitmr @mikunitmr 26日前
Win7+Excel2003でマクロを使って計算させたら100.000000000014になった。
mikunitmr @mikunitmr 26日前
10万回足したら999.999999999236になった。
east @1963_east 26日前
kartis56 あれ?三体問題がきっかけになってカオス理論が提唱されて、カオス理論そのものは三体問題に限らず解析的に解くのが不可能で、数値計算も上記の理由で解が得られない問題すべてを指すものじゃなかったでしたっけ?(自信ない)
kartis56 @kartis56 26日前
1963_east 経緯はそうですが、根本的には3体問題が解けないことに由来するので
Lyiase@ETHガチホなう @lyiase 26日前
浮動小数点はIEEE 754で規格化されてるので、何年経っても変わらないのは当たり前。あとx86FPUは昔から拡張倍精度(80bit)まで計算出来る
七枝七夏 @7eda7ca 26日前
10000回程度でそのぐらいの誤差がでるんだな decimalの存在意義がよく分かった
napia @naipern 26日前
「何ページ目ですか?」「2ページ目です」のくだりで何故かクスっときた
kumonopanya @kumonopanya 26日前
私PCの計算を信じないなら手で検算してってやつだな。
yuki🌾遠征が終わりましたご期待以上でした♪⚔ @yuki_obana 26日前
N進数(Nは2のべき乗以外)でfloat使わずに誤差をなくすにはN進数体系で定義しなおして使うのが一番なのかね?(´・ω・`)あまりそういう課題にぶつかることないのよね…
Husetsu @husetsu126 26日前
「変わったら困る」でそりゃそうだってなった。一斉に変えたらサマータイム導入や2000年問題より大変なことになりそう。しかしそれより確実にくる2036年問題が…
TBT1102 @TBT1102 26日前
jsでもなる。毎回roundしてる。
クリスセドン @sedooooooon 26日前
時蕎麦の逆みたいなことしてる
ネギ @negi__ 26日前
大きい数と小さい数との和の誤差に関しては「カハンの加算アルゴリズム」というものがあって, 工夫して足していけば誤差の蓄積を軽減できる
VitzRsTurbo @VitzRsTurbo 26日前
「性能上がれば精度も上がると思っている」本来、性能には速度性能以外にも精度性能とか堅牢性性能みたいなのも含まれるものだと思うんだけど、何故か速度の事しか皆言わないんだよなあ。
KITI @KITI_TW 26日前
0.01++===================================================================================================(疲れた)
ねこ博士 @kazukazu_ex 26日前
逆に言えば少数を絡ませないようにするか、精度に注意すればいいだけのこと(´・ω・`) とにかく信用できないから電卓で検算とかは愚の骨頂。
🍤💨の沼海老 @mtoaki 26日前
aikokuwww まじで? 小数点以下の2進数は何かの試験の時にやったきりで、いつもは下駄はかせて整数演算してた。
KPCG10 @KPCG10 26日前
「10進数演算命令エライ」「2進数の誤差ヒドイ」という単純な話ではなく、「通貨計算には10進数演算が必要で、科学技術演算には10進数演算は必要とは言えない」という事。10進数であっても 1/3=1.333...のような循環小数がある限り誤差は蓄積するので IEEE 浮動小数点は2進数のまま演算しているのですよね。その意味で言うとエクセルは「ワークシート全体を10進数で演算する」なんてオプションが欲しいところ。
prad_bitt @pradbitt42 25日前
KPCG10 通貨(金額)計算も、今は10進の通貨が支配的だからだいたいそれで通るけど、12進(昔の英国とか)だったら10進で逆に誤差が出るから……
gaheki @gaheki 25日前
まぁマシンパワー上がってるしその辺知らないド素人が触れる事も多くなった現状だと多少遅くなってもデフォルトを全て十進でやる設定あってもいいと思うんだ
m232796 @m232796 25日前
ポケコンBASICだと関数電卓兼ねてる都合上かBCD系の内部表現使ってることもあるね。PC-G850とかだとインタプリタなCでもコード書けるのだけどそこで扱う浮動小数点数もまたBCDだったのが面白かった。unionとかポインタキャストでfloatの内部表現見ると平然とBCD表現が出てくるっていう・・・w
m232796 @m232796 25日前
gaheki まとめの中にあるけど、10進数でも「三桁なら1/3は0.333で、これに3000かけても999」だから解決はしないんですよ…そのくせ速度は落ちてしまう。結局誤差が困る場所には誤差が出ないことを保証できる計算方式を明示して適用することになるので、そうでない場所は程々かつ高速な数値表現・計算方法に落ち着くのでしょうね。
ゴジラ @gojira_ku 25日前
kartis56 僕も専門ではないので間違ってるかも知れませんが、3体問題が解けないのはポアンカレの回帰定理から導かれるものですよね。ポアンカレの回帰定理はハミルトン力学の話だと思うのですが、カオスを示す系はハミルトン力学以外にもたくさんありますよね(計算機での四則演算など)。3体問題は微分方程式の解析解が得られない例の1つでしかないと思いますし、解析解が得られないからといって必ずカオスになるわけでもありません。3体問題のどこが本質的なのですか?
prad_bitt @pradbitt42 25日前
m232796 有理数として計算(分数として通分・約分しながら計算を進めていく)することで、ある程度の範囲では対応できるね。
m232796 @m232796 25日前
pradbitt42 分数・複素数辺りまでなら4つの値を組にしたプリミティブ型を用意して対応することはできると思う。けど、その次は数千ビットの値が表現できないだの三角関数で割り切れる値なのに誤差がみたいな話になるとも思う。最終的には数式処理システムを丸々一式・・・までは行かずとも演算子に遭遇するたびに内部に式を追記して適時式変形を掛けていく「値」とは呼び難い型でループ回数をカウントするような事になるのではないだろうか。
akima@財政お花畑 @akima9936 24日前
COBOLならちゃんと計算してくれそう
oshow2001 @oshow2001 23日前
0.01が切りが悪い数字に感じて、0.5/0.25/0.125/0.0625/0.03125/0.015625が切りの良い数字に感じるようになれば、プロ(廃人)。
Sainokuni_affair @SainokuniA 22日前
くそぉ・・・高校で数値の型を教わるときに先生がこれをやって見せてくれてればもっと飲み込めたハズ?なのに!
ポッカ @pokka80 22日前
なるほど二進数で割り切れない数字だと誤差が出るのか
tarosuke @tarosukenet 14日前
futamori それで気付いた。数値モン解かせたらそれで「解なし」になる可能性がある。
ログインして広告を非表示にする
ログインして広告を非表示にする