0

x整数が与えられたとしましょう(特に、2 で割り切れる1 桁でy満足します)。次に、それらの平均も整数であることを知っています。この中間点を の解像度に切り上げたいと思います。つまり、私の 2 つの入力が 75200 と 75300 の場合、平均は 75250 であり、最も近い値に切り上げられます(ただし、より大きな数を超えたり等しくなったりすることはありません) と、答えは 75200 になります。x <= y0avg = ((x+y) / 2)100100

最初にすべてを 100 で割り、次の浮動小数点演算を使用せずに、このロジックを実装するにはどうすればよいですか。

x + std::floor((y - x) * .5 * 100 + .5)*0.01

言い換えれば、浮動小数点値を使用せずに上記を行うにはどうすればよい100です0.01か?

4

2 に答える 2

3

あなたができる平均を計算するには

avg = (x + y) / 2

(ちなみに、整数の加算と 2 での除算は、小さなマイクロコントローラーでも非常に安価な操作です。)

これを最も近い100の倍数に丸めるには(浮動小数点の例に対応)、次のことができます

result = ((avg + 50) / 100) * 100

整数除算では、最も近い整数に切り捨てられます。を に変更する500常に切り捨てられ、 に変更すると99常に切り上げられます。

編集:この丸め方法は、負の数では機能しないことに注意してください。整数除算はゼロに向かって丸められるため、その場合は を減算する必要があります。常に切り捨てるに50は減算99し、常に切り上げるには減算0します。

于 2013-01-18T22:03:26.803 に答える
2

問題のある例には、強力な条件が必要です。

  • x と y の差は 100 以下である必要があります
  • y % 100 は 0 でなければなりません

したがって、ほとんどの場合、単純な丸め平均が最適です。

avg100 = avg - (avg % 100) + 100

トリッキーな部分は、条件なしで残りのエラーを修正することです-条件を回避したい場合、または操作が遅くなった場合。

このための最善の方法は、乗算を使用して式を 2 つに分割することです。

avg100 = avg - (avg % 100)
avg100 += 100 * !!(y - avg100)

ほとんどの場合、y は avg100 より大きくなります。この場合、!!演算子は 1 を返します。まれに、それらが等しい場合、0 が返され、値は変更されません。

(コンパイラが本当に '!!' 演算子の条件なしでコードを生成するかどうかはわかりませんが、バッターのアイデアはありません。可能であれば、生成されると思います。そうでない場合、このコード短くて分かりやすいです。)

また、次の式を使用して平均を計算できます。

avg = y - (y-x)/2

または、最適化のために分割をビット シフトに変更することもできます。

これは、両方の数値が偶数である必要はなく、同じパリティになるだけです。

于 2013-01-18T21:23:21.100 に答える