在寻找一种比ceil
本身更快ceil
运算符的方法时,我遇到了这个问题:
var ceilX = (X + 1) >> 0
哪种方法可以减少小数,但最终无法进行正确的ceil
操作,因为(1 + 1) >> 0 === 2
,而ceil(1)=== 1。
关于如何执行此操作有一个不同的问题here,但是思路让我想知道是否有办法在一个值上添加一个小于1的数字,然后使用按位移位来舍入它。在我看来它应该适用于所有可以表示为32位数字的东西,但我不知道如何得到真正接近1的数字。以无意义的微优化的名义,是否有一个好的这样做的方式?
答案 0 :(得分:0)
在非IE浏览器中,Number.EPSILON
属性表示一个值与大于一的最小值之间的差值。因此,为了获得最大数量,可以1-Number.EPSILON
您还可以通过递归地将1除以2得到calculate an Epsilon值,直到它等于零,然后从第二步的第二步中取出数字。这将产生比Number.EPSILON
更小的值。
两种方法都显示在下面的小提琴中,并与内部ceil函数进行比较,遗憾的是,这两种方法都没有完全匹配内部方法,但可以达到任意精度。比特移位方法也表明Chrome在标准功能上没有性能提升。因此,即使毫无意义的微观优化,这也无法实现。
答案 1 :(得分:0)
Number.EPSILON为X = 1
提供了正确答案,但对于较大的数字,最大数字n
小于1,(X + n) >> 0 === ceil(X)
基于数字的指数。这是基于双精度结构的方式,带有指数和有效数。有效数字的最后一位的精度基于指数,并给出所表示数字的精度。
具体而言,该数字可按如下方式计算:
var relEps = Number.EPSILON * ((1 << (((Math.log(X) / Math.LN2) | 0) - 1)) + 1)
之后:
(X + (1 - relEps)) >> 0 === ceil(X)
我很确定这比ceil(X)
慢,但想出来很有趣。
对于实际上比ceil
更快的内容,这会给出显示
(X + (1 - X * Number.EPSILON)) >> 0
适用于X !== 0
。这比天籁更快。