35bit その2
昨日適当に考えた、35bitの続き。
35bit→32bit×8のアルゴリズムとしてもっとも簡単な方法?は、
- 35bitの上位32bitを元の値として8個分複製
- 8個のうち、下位3bitが示す個数分だけ+1する
ってやればいい。
これでやるとたとえば、
35bit(16進数の下位) | 32bit内訳 | 32bitの合計 |
-9(10 111) | -2×1個+-1×7個 | -9 |
-8(11 000) | -1×8個 | -8 |
-7(11 001) | -1×7個+0×1個 | -7 |
中略 | ||
-1(11 111) | -1×1個+0×7個 | -1 |
0(00 000) | 0×8個 | 0 |
1(00 001) | 0×7個+1×1個 | 1 |
中略 | ||
7(00 111) | 0×1個+1×7個 | 7 |
8(01 000) | 1×8個 | 8 |
9(01 001) | 1×7個+2×1個 | 9 |
みたいな感じで、32BitのLSB刻みで35bit分の階調が得られる。
ただ、この方法は問題があり、正の最大方向でオーバーフローする。
切り捨てた状態で正の最大値を取りうるので、+1すればオーバーフローする。
2の補数表現で取りうる値は
- 35bit
- -17,179,869,184〜17,179,869,183
- 32bit
- −2,147,483,648〜2,147,483,647
- 32bit×8
- -17,179,869,184〜17,179,869,176
であり、正の方向で32bit×8よりも、35bitのほうが7大きいため、ここが表現できず、オーバーフローする…ってことでいいのか自信がなくなってきた。
指数で書くと、より問題が明らかになるかもしれない
- 35bit
- -(2^34)〜2^34-1
- 32bit
- -(2^31)〜2^31-1
- 32bit×8
- -(2^31*2^3)=-(2^34)〜(2^31-1)*(2^3)=(2^34-2^3)
やはり、表現できる範囲が狭く、7の分だけオーバーフローする。
まとめるとにすると、Nbitのデータを2^M個集めて、(N+M)bitを表現しようとして、上の方法で符号を作ると正の最大から2^M-1個は表現できない。ということか。
…ここまで書いて、これはTIがマルチビットでやっているサインマグニチュードを一般化した話だというのに気が付いた。
サインマグニチュードDACはPCM1704を例にすれば、24bitを表現するために23bit×2+1LSBで作られていて振幅の正負に二つのDACを割り振っている。
24bitに対して、23bit×2だと1少なくなるので、それを補うために1LSB追加してある。
これは、オーバーフローしない方法で、23bitに1を足しているようなものなので、やはり符号内で足しているとオーバーフローするのは確実なんだろうか。
外付けで1LSBを足すというのは、PCM1704みたいな初めからそれ用に作ったデバイスでないと難しいので、オーバーフローしない方法がないかな?と思って考えたが、足す代わりに引くようにすると負側でオーバーフローするし、正負に振るようにしても両方でオーバーフローするようになるので八方ふさがり。
結局飽和付き加算にして、7個分は諦めるっていうのがいいんじゃないか。
フィルタの係数を工夫すれば、ここに絶対に値が来ないようにするのはできると思う。