teratail header banner
teratail header banner
質問するログイン新規登録

回答編集履歴

1

微妙に間違っている部分を修正

2018/07/07 05:52

投稿

Chironian
Chironian

スコア23274

answer CHANGED
@@ -4,10 +4,10 @@
4
4
  ですので、実は0.16をピッタリ2進数で表現することができません。
5
5
  1.16 = 1.0 + 0.125 + 0.3125 + 0.0078125 + ...
6
6
  有限桁の2進数で表現するため、最後は切り捨てなどで丸められています。
7
- ですので、1.16の内部表現は、1.16よりほんの僅か小さな値です。
7
+ ですので、1.16の内部表現は、1.16よりほんの僅か小さな値になっているようです。
8
8
  それを25倍すると、29よりほんの僅か小さな値になります。それを整数へ単純に変換するのでまるっと小数点以下が切り捨てられて28になります。
9
9
 
10
- 整数へ変換ぜずにdoubleで受けても同じく29よりほんの僅か小さな値(例えば、28.9999999999)になりますが、doubleは切り捨てずに記録できます。そしてそれを表示する際、小数点以下の数値は有限丸められます。その際四捨五入されますので、ほんの僅か小さな値ですから四捨五入されると切り上げられるため、29になります。
10
+ 整数へ変換ぜずにdoubleで受けても同じく29よりほんの僅か小さな値(例えば、28.9999999999)になりますが、doubleは切り捨てずに記録できます。そしてそれを表示する際、小数点以下の数値は程度で丸められます。その際四捨五入されますので、9が四捨五入され切り上げられるため、29になります。
11
11
 
12
12
  対策はint型へ変換する際に四捨五入する(例えば[round](https://cpprefjp.github.io/reference/cmath/round.html))のが手っ取り早いです。
13
13
  (なお、負の数の四捨五入には要注意です。四捨を0に近い方へ切り上げる、もしくは、0から遠い方へ切り捨てる2種類のやり方があります。)