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

回答編集履歴

2

変なつなぎ修正

2018/03/04 04:12

投稿

swordone
swordone

スコア20675

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

左シフトではなく右シフト ついでにコメントの内容を盛り込んで修正

2018/03/04 04:12

投稿

swordone
swordone

スコア20675

answer CHANGED
@@ -1,13 +1,17 @@
1
- 「10で割る」ではなく、「0.1を掛ける」と考えてみましょう。十進数の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
- 2進数で1100110011001100を掛けて19ビット下げれば、結果的に10で割ったことになります。
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になります。