Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
プログラミングで小数計算すると なんで誤差が発生するのか?
Search
kumaGoro95
April 26, 2021
0
260
プログラミングで小数計算すると なんで誤差が発生するのか?
kumaGoro95
April 26, 2021
Tweet
Share
More Decks by kumaGoro95
See All by kumaGoro95
アジャイルの名を捨ててアジャイルをやる ─アジャイルに忌避感のある現場での“困りごと駆動”の実践─
kumagoro95
0
470
昭和の職場からアジャイルの世界へ
kumagoro95
1
690
DDDやってみたら 実装以前の領域での学びが深かった話
kumagoro95
13
8.6k
要件定義で得た学び・気づき
kumagoro95
4
2.6k
メンバーのわかりませんはチームが成長するチャンス.pdf
kumagoro95
1
430
ふりかえりでふりかえることしかできなかったジュニアチームが、次の打ち手を出せるチームになるのにやったこと
kumagoro95
3
1.5k
Githubのアクティビティ履歴からチームの健康状態を知る(Findy Teams使ってみた)
kumagoro95
0
600
導入事例を通じて理解するドメイン駆動設計
kumagoro95
0
420
The Assembly ~ directly controlling CPU ~
kumagoro95
0
430
Featured
See All Featured
Getting science done with accelerated Python computing platforms
jacobtomlinson
0
92
Leadership Guide Workshop - DevTernity 2021
reverentgeek
1
180
Crafting Experiences
bethany
0
26
Rebuilding a faster, lazier Slack
samanthasiow
85
9.3k
Code Review Best Practice
trishagee
74
19k
Agile that works and the tools we love
rasmusluckow
331
21k
Fashionably flexible responsive web design (full day workshop)
malarkey
408
66k
The Cost Of JavaScript in 2023
addyosmani
55
9.4k
Balancing Empowerment & Direction
lara
5
840
Fantastic passwords and where to find them - at NoRuKo
philnash
52
3.5k
Utilizing Notion as your number one productivity tool
mfonobong
2
190
Self-Hosted WebAssembly Runtime for Runtime-Neutral Checkpoint/Restore in Edge–Cloud Continuum
chikuwait
0
280
Transcript
プログラミングで小数計算すると なんで誤差が発生するのか? くまごろー ?
このテーマを選んだいきさつ • プログラミング学習を進めてると、「double/float型で小数計算すると誤差が 発生する」という現象に遭遇する • 参考書では「正確に計算したいときはBigDecimal型を使いましょう」とか言 われる 問1 そもそも、プログラミングで小数計算するとなんで誤差が発生するの? 問2 なんでBigDecimal型で計算すると誤差が発生しないの?
1 誤差が出るってどういうこと?
double/float型で計算すると → 答えは「0.2」のはずなのに、誤差が生じる double num1 = 1.2; double num2 = 1.0;
System.out.println(num1 - num2); //0.19999999999999996
なぜこうなるのか? Q A コンピュータは2進数で計算している
• 「0」と「1」という2個の数字を使って数を表す • その桁の数値が「2」になると桁上がりする 2進数って? 10進数 2進数 1 1 2
10 3 11 4 100 4桁目 3桁目 2桁目 1桁目 8 4 2 1 例:2進数の「1111」を 10進数に直すと... → 8+4+2+1 = 15 になる
2進数での小数の表し方 1 1 1 . 1 1 1 1 100
10 1 1/10 1/100 1/1000 1/10000 〇「111.1111」という数字があるとする これが10進数表記だったら・・・ <各桁の重み>
2進数での小数の表し方 1 1 1 . 1 1 1 1 4
2 1 1/2 1/4 1/8 1/16 〇「111.1111」という数字があるとする では、2進数だったら? 2進数の「111.1111」を10進数に直すと → (4+2+1) + (0.5 + 0.25 + 0.125 + 0.0625) = 7.9375 2の倍数の分母を持つ分数でないと表せない
2 誤差はどのように発生しているのか
ケース1:循環小数 double num1 = 1.2; double num2 = 1.0;
System.out.println(num1 - num2); //0.19999999999999996 → 「0.2」は2進数で表せない (2進数だと「0.001100110011...」循環小数に)
double num1 = 0.1234; double num2 = 0.000000000000000004321; System.out.println(num1 +
num2); //0.1234 ケース2:情報落ち → double/float型は浮動小数点数(桁数が有限)なので、 正規化が行われる(切り捨てられる)
浮動小数点数とは ↓のような指数表記で小数を表記する方法。 例:2進数の-0.0001の場合(10進数だと0.0625) - -3 - 0.1 × 2 符号
仮数 指数 → 表記できる桁数が増える
浮動小数点数とは
- - 3 - 0.1 × 2 符号 仮数 指数 符号 (1Bit) 指数 (11Bit) 仮数 (52Bit) 〇 double型(64ビット)の場合 → 仮数が52ビット以上だと、切り捨てられる
3 なんでBigDecimalを使うと 誤差が生じないの?
• 「整数×10のマイナス乗」という式で数値を表現 BigDecimalの仕組み BigDecimalは、次のように値を保持している -scale unscaledValue×10 • 整数は小数と違い、2進数でも(何進数でも)全ての数値を表す ことができる。 10進数「1.2」の場合...
-1 12 × 10
ご清聴ありがとうございました