以前の実装はすべて丸めを使用していないため、大きなエラーが発生します。固定小数点演算でこれを行う方法は次のとおりです。X.1u prevision を使用しています (小数部分に 1 LSB を使用)。
//center = (max_x + min_x) / 2
center = max_x + min_x // zero error here
// distance = old_x - center
distance = (old_x << 1) - center // zero error here
//new_x = center + (distance * factor)
new_x = (**1** + center + (distance * factor)) >> 1
return new_x
factor が固定小数点 (整数) であり、N ビットが分数を表す場合、new_x は次のように計算できます。
new_x = ( (1 << N) + (center << N) + (distance * factor) ) >> (N + 1)
- (center << N)は N+1 個の小数ビットを持ちます
- 距離 * 係数には N+1 個の小数ビットがあります
- (1 << N)は、上記の固定小数点精度で1 << (N+1)が「1」であるため、「半分」です。
各部分を理解したら、上記の行を圧縮できます。
new_x = ( ((1 + center) << N) + (distance * factor) ) >> (N + 1)
もちろん、使用される整数型は十分に大きくなければなりません。有効な範囲が不明な場合は、この関数への入力と他の何かを確認する必要があります。ほとんどの場合、これは必要ありません。
これは、固定小数点演算と同じくらい優れています。これは、ハードウェア回路が整数演算を実行する方法です。