小数点数の量子化
某掲示板に投稿したもの
X[0.0 〜 2.0]の値を取る小数点数をY[0 .. 31]の整数型に量子化することを考える。普通に考えるとこうなる。
- X が 2.0 を含まない場合
- Y = trunc(X * 32 / 2.0)
- X が 2.0 を含む場合(Z = X * 31 / 2.0 と置く)
- Y = trunc(Z)
- Y = trunc(Z + 0.5) *1
X が 2.0 を含まない場合は全く問題ない。しかしそうで無い場合は2-2を使っても
- 0.0 <= Z < 0.5 → Y = 0
- 0.5 <= Z < 1.5 → Y = 1
- 30.5 <= Z <= 31.0 → Y = 31 *2
つまりY=0, 31の場合だけ、とれるZの範囲が半分になってしまう。この場合の量子化を正確に行うのは少し難しい。
改良案1)
- Z = X * (32 - delta) / 2.0 (deltaは適度に小さい数。Xが整数値ならdelta = 1)
- Y = trunc(Z)
としてYを計算する方法がある。つまり 0.0 <= X <= 2.0 の値を 0.0 <= Z <= 31.99999... に写像してしまえばいい。
改良案2)
X = 2.0 や Y = 32 の値だけを特別扱いする。つまり、
- Y = trunc(X * 32 / 2.0)
- if (Y == 32) Y = 31 or Y -= (Y >= 32) or Y -= (Y >> 5)
としてしまう方法もある。