2.9999999999999999 >> .5?

后端 未结 10 1828
逝去的感伤
逝去的感伤 2021-02-07 15:32

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

10条回答
  •  臣服心动
    2021-02-07 16:26

    I suspect that converting 2.9999999999999997779553950749686919152736663818359374999999 to it's binary representation would be enlightening. It's probably only 1 bit different from true 3.

    Good guess, but no cigar. As the double precision FP number has 53 bits, the last FP number before 3 is actually (exact): 2.999999999999999555910790149937383830547332763671875

    But why it is 2.9999999999999997779553950749686919152736663818359375

    (and this is exact, not 49999... !)

    which is higher than the last displayable unit ? Rounding. The conversion routine (String to number) simply is correctly programmed to round the input the the next floating point number.

    2.999999999999999555910790149937383830547332763671875

    .......(values between, increasing) -> round down

    2.9999999999999997779553950749686919152736663818359375

    ....... (values between, increasing) -> round up to 3

    3

    The conversion input must use full precision. If the number is exactly the half between those two fp numbers (which is 2.9999999999999997779553950749686919152736663818359375) the rounding depends on the setted flags. The default rounding is round to even, meaning that the number will be rounded to the next even number.

    Now

    3 = 11. (binary)

    2.999... = 10.11111111111...... (binary)

    All bits are set, the number is always odd. That means that the exact half number will be rounded up, so you are getting the strange .....49999 period because it must be smaller than the exact half to be distinguishable from 3.

提交回复
热议问题