我需要将数字转换成最小的log2 +1,但我有一个问题,在32位Ruby中,log2(8) = 2.9999999999999996。
输入(pos)和输出(level)应该是:
1 -> 1
2-3 -> 2
4-7 -> 3
8-15 -> 4
16-31 -> 5
and so on..我的公式:
pos = 8
level = ( Math.log(pos,2) + 1 ).to_i
# 3 (wrong) in 32-bit Ruby
# 4 (correct) in 64-bit Ruby是否有更多的方法来防止这种情况发生,或者是否有任何其他公式可以将pos转换为更正level,如上面所示?
发布于 2014-09-25 05:31:33
pos = 8
level = 0
until pos < 2
level += 1
pos /= 2
end
level + 1 #=> 4发布于 2014-09-25 05:40:26
下面是另一种计算整数的泛对数的有趣方法:
0.upto(Float::INFINITY).find{|e| x - base**e < base }发布于 2014-09-25 07:21:10
IEEE 754-2008 binary32的最大可表示值是(2−2**(−23)) × 2**127,因此存储在二进制32中的数字的base 2 log小于十进制128。因为舍入误差是1的一个很小的分数,所以我们可以取最近的整数,看看2到那个整数幂是否等于给定的数。如果是的话,返回整数幂;否则返回nil,这意味着它不是2的幂。
def log_2_if_integer(n)
x = Math.log(n,2).round(0).to_i
(2**x == n) ? x : nil
end
log_2_if_integer(4) #=> 2
log_2_if_integer(512) #=> 9
log_2_if_integer(3) #=> nil换句话说,由于日志小于128个,舍入错误不能生成一个值x,使任何整数m != 0 (正整数或负整数m != 0)都具有2**(x+m) == n。
https://stackoverflow.com/questions/26031075
复制相似问题