回答編集履歴
2
変なつなぎ修正
answer
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
「10で割る」ではなく、「0.1を掛ける」と考えてみましょう。
|
2
2
|
さらにシフト演算を利用すべく、「整数を掛けてシフトする」という計算をします。
|
3
|
-
そのため
|
3
|
+
その際の誤差を小さくするため、最初に掛ける整数の有効数字の桁数なるべく多くとります。
|
4
4
|
この作業の段階で対象の数字は16ビット以下なので、16ビットまでの整数であれば、
|
5
5
|
掛けても(符号なし整数の範囲で)オーバーフローしないということになります。
|
6
6
|
なので、整数部を16ビット取るように0.1の二進表記を変形します。
|
1
左シフトではなく右シフト ついでにコメントの内容を盛り込んで修正
answer
CHANGED
@@ -1,13 +1,17 @@
|
|
1
|
-
「10で割る」ではなく、「0.1を掛ける」と考えてみましょう。
|
1
|
+
「10で割る」ではなく、「0.1を掛ける」と考えてみましょう。
|
2
|
+
さらにシフト演算を利用すべく、「整数を掛けてシフトする」という計算をします。
|
3
|
+
そのためには、最初に掛ける整数の有効数字の桁数が多いほうが誤差が少なくなります。
|
4
|
+
この作業の段階で対象の数字は16ビット以下なので、16ビットまでの整数であれば、
|
5
|
+
掛けても(符号なし整数の範囲で)オーバーフローしないということになります。
|
6
|
+
なので、整数部を16ビット取るように0.1の二進表記を変形します。
|
7
|
+
|
2
|
-
0.00011001100110011001100...で
|
8
|
+
十進数の0.1は二進法では0.00011001100110011001100...(2)なので、
|
3
9
|
0.00011001100110011001100...(2)
|
4
|
-
=0.11001100110011001100...(2)*2^-3
|
10
|
+
=0.11001100110011001100...(2)*2^-3 (小数首位まで0を指数表記に移す)
|
5
|
-
=1100110011001100.1100...(2)*2^-(3+16)
|
11
|
+
=1100110011001100.1100...(2)*2^-(3+16) (16ビットの有効数字を取るため16桁分指数に移す)
|
6
|
-
となります。「*2^-(3+16)」の部分は(3+16)ビットだけ
|
12
|
+
となります。「*2^-(3+16)」の部分は(3+16)ビットだけ右シフトと考えられるので、
|
7
|
-
|
13
|
+
1100110011001100(2)を掛けて19ビット下げれば、結果的に10で割ったことになります。
|
8
|
-
掛け算する時点で元の数字が二進数で16ビット以下なので、符号なし整数の範囲で考えれば
|
9
|
-
16ビットまでの掛け算であればオーバーフローしないことになります。
|
10
|
-
ただし、1100110011001100では0.1倍に満たず、10の倍数などの場合は切り捨てが起きて
|
14
|
+
ただし、1100110011001100(2)では0.1倍に満たず、10の倍数などの場合は切り捨てが起きて
|
11
15
|
0.1倍より1小さい値が出てしまう可能性があります。
|
12
|
-
そのため掛ける数を1増やし、1100110011001101にしているのでしょう。
|
16
|
+
そのため掛ける数を1増やし、1100110011001101(2)にしているのでしょう。
|
13
17
|
これを10進数に直すと、52429になります。
|