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
210
プログラミングで小数計算すると なんで誤差が発生するのか?
kumaGoro95
April 26, 2021
Tweet
Share
More Decks by kumaGoro95
See All by kumaGoro95
昭和の職場からアジャイルの世界へ
kumagoro95
1
380
DDDやってみたら 実装以前の領域での学びが深かった話
kumagoro95
14
8.3k
要件定義で得た学び・気づき
kumagoro95
4
2.4k
メンバーのわかりませんはチームが成長するチャンス.pdf
kumagoro95
1
370
ふりかえりでふりかえることしかできなかったジュニアチームが、次の打ち手を出せるチームになるのにやったこと
kumagoro95
3
1.3k
Githubのアクティビティ履歴からチームの健康状態を知る(Findy Teams使ってみた)
kumagoro95
0
520
導入事例を通じて理解するドメイン駆動設計
kumagoro95
0
330
The Assembly ~ directly controlling CPU ~
kumagoro95
0
360
非エンジニアがドメイン駆動設計(DDD)について説明してみる。
kumagoro95
1
340
Featured
See All Featured
JavaScript: Past, Present, and Future - NDC Porto 2020
reverentgeek
47
5.2k
Cheating the UX When There Is Nothing More to Optimize - PixelPioneers
stephaniewalter
280
13k
Fight the Zombie Pattern Library - RWD Summit 2016
marcelosomers
233
17k
[RailsConf 2023 Opening Keynote] The Magic of Rails
eileencodes
28
9.3k
Facilitating Awesome Meetings
lara
52
6.2k
Let's Do A Bunch of Simple Stuff to Make Websites Faster
chriscoyier
507
140k
Imperfection Machines: The Place of Print at Facebook
scottboms
267
13k
Principles of Awesome APIs and How to Build Them.
keavy
126
17k
Product Roadmaps are Hard
iamctodd
PRO
50
11k
Learning to Love Humans: Emotional Interface Design
aarron
273
40k
Keith and Marios Guide to Fast Websites
keithpitt
411
22k
Raft: Consensus for Rubyists
vanstee
137
6.8k
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
ご清聴ありがとうございました