32 ビット整数 (32 エントリのみ) のすべての 2 のべき乗を保持することは大したことではありません。それが存在するはずの場所をすばやくバイナリ検索します。そうすれば、どの数値に近いかを簡単に把握できます。高い数値と低い数値から減算して腹筋を取得します。次に、どちらに追加するかを簡単に決定できます。
数値の基数 2 の対数を取得し、それを使用して配列にインデックスを付けることで、検索を回避できる場合があります
更新:このコードは十分にテストされていないことを思い出してください。
#include <array>
#include <cmath>
#include <iostream>
const std::array<unsigned int,32> powers =
{
1,1<<1,1<<2,1<<3,1<<4,1<<5,1<<6,1<<7,1<<8,1<<9,1<<10,1<<11,1<<12,1<<13,1<<14,
1<<15,1<<16,1<<17,1<18,1<<19,1<<20,1<<21,1<<22,1<<23,1<<24,1<<25,1<<26,1<<27,
1<<28,1<<29,1<<30,1<<31 -1
};
std::array<unsigned int,32> powers_of_two() {
std::array<unsigned int,32> powers_of_two{};
for (unsigned int i = 0; i < 31; ++i) {
powers_of_two[i] = 1 << i;
}
powers_of_two[31]=~0;
return powers_of_two;
}
unsigned int round_to_closest(unsigned int number) {
if (number % 2 == 0) return number;
unsigned int i = std::ceil(std::log2(number));
//higher index
return (powers[i]-number) < (number - powers[i-1]) ?
++number:--number;
}
int main() {
std::cout << round_to_closest(27) << std::endl;
std::cout << round_to_closest(23) << std::endl;
return 0;
}
私は 2 ^ 31 を表すことができないので、それに最も近い unsigned int (すべて 1) を使用しました。これは、すべてのケースのうち 1 つのケースが間違った結果を生成することを意味しますが、それは大したことではないと考えました。
std::vector<bool>
私は、1 を足したり 1 を引いたりするために、非常に大きなルックアップ テーブルとして aを使用できると考えていました。