当计算大于49的数字的log2值时,visual studio 2015和gcc4.8都会给出错误的结果。
double log2_49_ones = log2(0x1FFFFFFFFFFFF); // result is 49 - should be 48
double log2_48_ones = log2(0xFFFFFFFFFFFF); // result is 47 - correct result
知道这是不是一个bug?
答案 0 :(得分:1)
log2()
将float / double数作为参数,因此在隐式转换期间可能会丢失精度。
你可以使用这个技巧:
unsigned int number = 59029; // example
int targetlevel = 0;
while (number >>= 1) ++targetlevel;
由answer提供。
答案 1 :(得分:0)
相同的浮点格式用于多种语言,因此这可能是一般问题。例如,在Chrome 58 for Windows中的Javascript中,我看到的结果与您相同。
Math.log2(0x1FFFFFFFFFFFF)
49 // this really is 49, i.e. if you subtract 49, it is 0
Math.log2(0xFFFFFFFFFFFF)
47.99999999999999 // This would be 47 if put into an int
我们不要把它称为错误:它正在接近浮点格式和/或软件库的功能极限。
如果你想要正确的答案大约2 ^ 53,那么对于较大的数字,你可以进行一些整数除法,这样log2就可以在其舒适的范围内保持运行。在Javascript(抱歉!请不要杀我),例如
function betterLog2 (x) {
if (x<2**32){
return Math.log2(x)
} else {
return 32 + Math.log2(parseInt(x/(2**32)))
}
}
似乎为2 ^ 53-1之间的整数给出了正确的答案。
同样的原则应该适用于任何语言和实施。我怀疑任何语言实现都会有一个库为2 ** 32以下的值舍入log 2。
希望它有帮助8 - )