2.9999999999999999>> 0.5? [英] 2.9999999999999999 >> .5?

查看:145
本文介绍了2.9999999999999999>> 0.5?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我听说你可以.5右移位,而不是使用Math.floor()的数字。我决定检查其限制,以确保它是一个合适的替代者,于是我查了以下值,得到了谷歌浏览器,结果如下:

 
2.5 >> 0.5 == 2;
2.9999 >> 0.5 == 2;
2.999999999999999 >> 0.5 == 2; // 15 787-9
2.9999999999999999 >> 0.5 == 3; // 16 787-9

一些摆弄后,我发现两个可能的最高值,.5时右移,将产生22.9999999999999997779553950749686919152736663818359374999999¯(与9重复)在Chrome和Firefox。数是2.9999999999999997779¯在IE中。

我的问题是:什么是数字.0000000000000007779553950749686919152736663818359374的意义是什么?这是一个非常陌生的号码,这确实引起了我的好奇心。

我一直在试图寻找一个答案,或者至少某种模式,但我觉得我的问题在于我真的不明白,按位运算。我明白原则的想法,但.5移位序列没有任何意义的给我。任何帮助是AP preciated。

有关备案,怪异的数字序列与2 ^ x的变化。以下数字的最高可能值仍正常截断:


0:0.9999999999999999444888487687421729788184165954589843749¯
1:1.9999999999999999888977697537484345957636833190917968749¯
2-3:X +.99999999999999977795539507496869191527366638183593749¯
4-7:X +.9999999999999995559107901499373838305473327636718749¯
8-15:X +.999999999999999111821580299874767661094665527343749¯
...等等


解决方案

其实,你只是结束了做地板()的第一个操作,没有任何浮点运算回事。由于左移位,右移位位运算只有整数操作数是有意义的,JavaScript引擎是两个操作数第一转换为整数:

  2.999999>> 0.5

变成了:

  Math.floor(2.999999)GT;> Math.floor(0.5)

这又是:

  2  - ;> 0

由0位表示不做转变,因此你结束了第一个操作,只需截断为整数。移

的SpiderMonkey的源$ C ​​$ c的:

 开关(OP){
  案例JSOP_LSH:
  案例JSOP_RSH:
    如果(js_DoubleToECMAInt32(CX,D&安培;!I))//同Math.floor()
        返回JS_FALSE;
    如果(js_DoubleToECMAInt32(CX,D2,和放大器;!j)条)//相同Math.floor()
        返回JS_FALSE;
    J&安培; = 31;
    D =(OP == JSOP_LSH)? I<<记者:I>>焦耳;
    打破;

您看到某些数字四舍五入,是由于这样的事实JavaScript引擎无法处理十进制数字超出了一定的precision,因此您的号码最终得到四舍五入到下一个整数。在你的浏览器试试这个:

 警报(2.999999999999999);

您会得到2.999999999999999。现在尝试增加一个9:

 警报(2.9999999999999999);

您会得到一个3。

I heard that you could right-shift a number by .5 instead of using Math.floor(). I decided to check its limits to make sure that it was a suitable replacement, so I checked the following values and got the following results in Google Chrome:


2.5 >> .5 == 2;
2.9999 >> .5 == 2;
2.999999999999999 >> .5 == 2;  // 15 9s
2.9999999999999999 >> .5 == 3;  // 16 9s

After some fiddling, I found out that the highest possible value of two which, when right-shifted by .5, would yield 2 is 2.9999999999999997779553950749686919152736663818359374999999¯ (with the 9 repeating) in Chrome and Firefox. The number is 2.9999999999999997779¯ in IE.

My question is: what is the significance of the number .0000000000000007779553950749686919152736663818359374? It's a very strange number and it really piqued my curiosity.

I've been trying to find an answer or at least some kind of pattern, but I think my problem lies in the fact that I really don't understand the bitwise operation. I understand the idea in principle, but shifting a bit sequence by .5 doesn't make any sense at all to me. Any help is appreciated.

For the record, the weird digit sequence changes with 2^x. The highest possible values of the following numbers that still truncate properly:

for 0: 0.9999999999999999444888487687421729788184165954589843749¯
for 1: 1.9999999999999999888977697537484345957636833190917968749¯
for 2-3: x+.99999999999999977795539507496869191527366638183593749¯
for 4-7: x+.9999999999999995559107901499373838305473327636718749¯
for 8-15: x+.999999999999999111821580299874767661094665527343749¯
...and so forth

解决方案

Actually, you're simply ending up doing a floor() on the first operand, without any floating point operations going on. Since the left shift and right shift bitwise operations only make sense with integer operands, the JavaScript engine is converting the two operands to integers first:

2.999999 >> 0.5

Becomes:

Math.floor(2.999999) >> Math.floor(0.5)

Which in turn is:

2 >> 0

Shifting by 0 bits means "don't do a shift" and therefore you end up with the first operand, simply truncated to an integer.

The SpiderMonkey source code has:

switch (op) {
  case JSOP_LSH:
  case JSOP_RSH:
    if (!js_DoubleToECMAInt32(cx, d, &i)) // Same as Math.floor()
        return JS_FALSE;
    if (!js_DoubleToECMAInt32(cx, d2, &j)) // Same as Math.floor()
        return JS_FALSE;
    j &= 31;
    d = (op == JSOP_LSH) ? i << j : i >> j;
    break;

Your seeing a "rounding up" with certain numbers is due to the fact the JavaScript engine can't handle decimal digits beyond a certain precision and therefore your number ends up getting rounded up to the next integer. Try this in your browser:

alert(2.999999999999999);

You'll get 2.999999999999999. Now try adding one more 9:

alert(2.9999999999999999);

You'll get a 3.

这篇关于2.9999999999999999&GT;&GT; 0.5?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆