首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >将数字转换为log2

将数字转换为log2
EN

Stack Overflow用户
提问于 2014-09-25 05:18:41
回答 3查看 547关注 0票数 1

我需要将数字转换成最小的log2 +1,但我有一个问题,在32位Ruby中,log2(8) = 2.9999999999999996。

输入(pos)和输出(level)应该是:

代码语言:javascript
复制
1 -> 1
2-3 -> 2
4-7 -> 3
8-15 -> 4
16-31 -> 5
and so on..

我的公式:

代码语言:javascript
复制
pos = 8 
level = ( Math.log(pos,2) + 1 ).to_i
# 3 (wrong) in 32-bit Ruby
# 4 (correct) in 64-bit Ruby

是否有更多的方法来防止这种情况发生,或者是否有任何其他公式可以将pos转换为更正level,如上面所示?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2014-09-25 05:31:33

代码语言:javascript
复制
pos = 8
level = 0
until pos < 2
  level += 1
  pos /= 2
end
level + 1 #=> 4
票数 2
EN

Stack Overflow用户

发布于 2014-09-25 05:40:26

下面是另一种计算整数的泛对数的有趣方法:

代码语言:javascript
复制
0.upto(Float::INFINITY).find{|e| x - base**e < base }
票数 1
EN

Stack Overflow用户

发布于 2014-09-25 07:21:10

IEEE 754-2008 binary32的最大可表示值是(2−2**(−23)) × 2**127,因此存储在二进制32中的数字的base 2 log小于十进制128。因为舍入误差是1的一个很小的分数,所以我们可以取最近的整数,看看2到那个整数幂是否等于给定的数。如果是的话,返回整数幂;否则返回nil,这意味着它不是2的幂。

代码语言:javascript
复制
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

票数 -1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/26031075

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档