保留32位整數的所有2的冪(只有32個條目)對它應該在的位置進行快速二分搜索並不是什麼大事。然後你可以很容易地找出哪個通過從較高和較低的數字中減去並獲得絕對值,數字更接近。然後,您可以輕鬆決定添加哪一個。
您可以通過把你的號碼的數底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我用最接近的無符號整型它(全1),這意味着1例出所有的人都會產生不正確的結果,我想這不是一個大應對。
我在想,你可以使用一個std::vector<bool>
作爲一個非常大的查找表來添加1或減1,看起來像是對我來說似乎是一個操作,似乎運行得相當快的矯枉過正。
所以不做任何改動做甚至整數 – aaronman
對於我的用例,甚至整數不會改變。 – drawnonward
看看我的代碼,它包含日誌索引的解決方案之一,我要使第一個函數爲constexpr,但你得到的點 – aaronman