Javascript bitshift替代math.round

Javascript bitshift替代math.round,javascript,Javascript,对于上述情况,JavaScripts bitshift的语法是什么 使用整数而不是浮点 谢谢不幸的是,位移位操作通常只对整数起作用。变量是整数还是浮点数?如果var2是二(2^k)的幂,则可以 写 (var1>>k)您可以执行(var | 0)-这会将数字截断为整数,但您始终会得到下限值。如果要对其进行舍入,则需要额外的If语句,但在本例中,Math.round无论如何都会更快。[UPDATED] 快速回答: var intResult=(((var1/var2)+0.5)>1)*var2; 它

对于上述情况,JavaScripts bitshift的语法是什么

使用整数而不是浮点


谢谢

不幸的是,位移位操作通常只对整数起作用。变量是整数还是浮点数?

如果var2是二(2^k)的幂,则可以 写

(var1>>k)您可以执行
(var | 0)
-这会将数字截断为整数,但您始终会得到下限值。如果要对其进行舍入,则需要额外的
If
语句,但在本例中,
Math.round
无论如何都会更快。

[UPDATED] 快速回答:

var intResult=(((var1/var2)+0.5)>1)*var2;

它比问题中提供的
Math.round()
方法快,并且提供了完全相同的值

根据我的测试,位移动速度提高了10%到20%。下面是一些比较这两种方法的更新代码

下面的代码有四个部分:第一,它创建10000组两个随机整数;第二,它对OP的问题进行取整,存储值供以后比较,并记录总的执行时间;第三,它进行等效的位移位,存储值供以后比较,并记录执行时间;第四,它比较取整和位移位值以查找任何差异。它应报告无异常

请注意,这应该适用于所有正值和非零值。如果代码遇到分母为零,它将引发错误,我非常确定负值不会正确移位,尽管我没有测试过

(var1>>k)<<k
var arr1=[],
arr2=[],
arrFloorValues=[],
arrshiftvalue=[],
intFloorTime=0,
intShiftTime=0,
这是一个很好的建议
我
//第一步:创建随机值进行比较
对于(i=0;i<100000;i++){
arr1.push(Math.round(Math.random()*1000)+1);
arr2.push(Math.round(Math.random()*1000)+1);
}
//第二步:测试数学的速度
var intStartTime=new Date().getTime();
对于(i=0;i1)*arr2[i]);
}
log(“移位:”+(new Date().getTime()-intStartTime));
//第四步:确认Math.round()和bit shift生成相同的值
intMaxAsserts=100;
对于(i=0;i
您应该能够通过添加0.5,然后去掉小数来对任何数字进行四舍五入

var arr1 = [],
    arr2 = [],
    arrFloorValues = [],
    arrShiftValues = [],
    intFloorTime = 0,
    intShiftTime = 0,
    mathround = Math.round, // @trinithis's excellent suggestion
    i;

// Step one: create random values to compare
for (i = 0; i < 100000; i++) {
    arr1.push(Math.round(Math.random() * 1000) + 1);
    arr2.push(Math.round(Math.random() * 1000) + 1);
}

// Step two: test speed of Math.round()
var intStartTime = new Date().getTime();
for (i = 0; i < arr1.length; i++) {
    arrFloorValues.push(mathround(arr1[i] / arr2[i]) * arr2[i]);
}
console.log("Math.floor(): " + (new Date().getTime() - intStartTime));

// Step three: test speed of bit shift
var intStartTime = new Date().getTime();
for (i = 0; i < arr1.length; i++) {
    arrShiftValues.push( ( ( ( (arr1[i] / arr2[i]) + 0.5) << 1 ) >> 1 ) * arr2[i]);

}
console.log("Shifting: " + (new Date().getTime() - intStartTime));

// Step four: confirm that Math.round() and bit-shift produce same values
intMaxAsserts = 100;
for (i = 0; i < arr1.length; i++) {
    if (arrShiftValues[i] !== arrFloorValues[i]) {
        console.log("failed on",arr1[i],arr2[i],arrFloorValues[i],arrShiftValues[i])
        if (intMaxAsserts-- < 0) break;
    }
}
所以原始表达式可以用这个来求解(而不是较慢的Math.round)

((var1/var2+0.5)| 0)*var2

运行下面的代码段以测试不同的值

函数updateAnswer(){
var A=document.getElementById('A').value;
var B=document.getElementById('B')。值;
var h=“数学轮(A/B)*B=“+(数学轮(A/B)*B)+”;
h+=“
”; h+=“((A/B+0.5)| 0)*B=“+((A/B+0.5)| 0)*B+”; document.getElementById('ans').innerHTML=h; }
*{font-family:courier}
A:

B:



pn和sn只是整数的变量。也可以是(数学四舍五入(2/4)*4)。谢谢。你确定你是指位移位吗?位移位会使每次移位的值增加一倍或一半。如果var2始终是2的幂,那么它会工作,但如果var2是奇数,则处理它的逻辑开销将大于将其除以。请阅读几遍,仍然不理解你的问题。请重新阅读短语你要做的是,零的位移位(>>0)不总是向下舍入吗?所以,只要找到一个可以根据变量的值向上或向下舍入的位移位公式。>>0是不可操作的。你想做什么?pn和sn只是整数的变量。也可以是(Math.round(2/4)*4)。谢谢。我不想检查,但可能要直接参考
Math.round
,比如
var round=Math.round;
,这样会得到更准确的结果。没错。在Firefox和Chrome上,它的执行时间减少了约2%。在最新的Safari中(大约快5倍),差异可以忽略不计。我确实认为我的位移位数学有问题。我正在努力纠正这个问题。加上0.5显然会留下与数学相同的值。round()。更新答案。我只测试了正整数,我想这对任何小于1的整数都不起作用。谢谢你安德鲁,还有这个。安德鲁,我用谷歌搜索了好几天,试图找到任何关于更有效舍入方法的文章、博客或任何东西。我找不到关于这个问题的任何注释。你是太棒了!再次感谢!非常乐意帮忙。这是一个有趣的问题!我也从中学到了一些东西。早在小学,我就知道正好位于两个整数之间的十进制数应该舍入到最近的偶数(即1.5->2,2.5->2,3.5->4等)。在JS中,这些数字总是四舍五入(朝向正无穷大)。这个花边大大简化了逻辑!如果你的目标是32位以下的数字,那就不好了:@JorgeFuentesGonzález大于*@GustvandeWal是的,你是对的。我的错。
var arr1 = [],
    arr2 = [],
    arrFloorValues = [],
    arrShiftValues = [],
    intFloorTime = 0,
    intShiftTime = 0,
    mathround = Math.round, // @trinithis's excellent suggestion
    i;

// Step one: create random values to compare
for (i = 0; i < 100000; i++) {
    arr1.push(Math.round(Math.random() * 1000) + 1);
    arr2.push(Math.round(Math.random() * 1000) + 1);
}

// Step two: test speed of Math.round()
var intStartTime = new Date().getTime();
for (i = 0; i < arr1.length; i++) {
    arrFloorValues.push(mathround(arr1[i] / arr2[i]) * arr2[i]);
}
console.log("Math.floor(): " + (new Date().getTime() - intStartTime));

// Step three: test speed of bit shift
var intStartTime = new Date().getTime();
for (i = 0; i < arr1.length; i++) {
    arrShiftValues.push( ( ( ( (arr1[i] / arr2[i]) + 0.5) << 1 ) >> 1 ) * arr2[i]);

}
console.log("Shifting: " + (new Date().getTime() - intStartTime));

// Step four: confirm that Math.round() and bit-shift produce same values
intMaxAsserts = 100;
for (i = 0; i < arr1.length; i++) {
    if (arrShiftValues[i] !== arrFloorValues[i]) {
        console.log("failed on",arr1[i],arr2[i],arrFloorValues[i],arrShiftValues[i])
        if (intMaxAsserts-- < 0) break;
    }
}
var anyNum = 3.14;
var rounded = (anyNum + 0.5) | 0;