3

I have seen many people using bitwise operators to remove decimal parts, or round off a number, using bitwise operators.

But, I want to know how actually this work?

let a = 13.6 | 0; //a == 13
let b = ~~13.6; // b == 13

I did search for the same. The best I could find was this.
People there are talking about efficiency, pros and cons. I am interested in how this actually works?

All bitwise operations except unsigned right shift, >>>, work on signed 32-bit integers. So using bitwise operations will convert a float to an integer.

So using bitwise operations will convert a float to an integer. But how?

sujeet
  • 3,480
  • 3
  • 28
  • 60
  • What is your understanding of integer and floating point values? What exactly do you want to know - are you interested in the algorithm and how it treats edge cases, are you looking for the engine implementation, do you want to know what happens to the individual bits in RAM? – Bergi Apr 26 '20 at 12:08
  • _do you want to know what happens to the individual bits in RAM?_ This is what I am looking for? How doing `OR` with fractional numbers trims its decimal parts? – sujeet Apr 26 '20 at 12:10
  • 1
    Ok. well, it doesn't deal with individual bits. It treats the 64 bits as a double floating point representation, and does math with them to arrive at a whole number. – Bergi Apr 26 '20 at 12:14
  • 1
    https://2ality.com/2012/02/js-integers.html – Bergi Apr 26 '20 at 12:15

1 Answers1

3

With |, its two operators are converted to integers through the NumberBitwiseOp operation, which calls ToInt32 on both operators, whose process is:

The abstract operation ToInt32 takes argument argument. It converts argument to one of 232 integer values in the range -231 through 231 - 1, inclusive. It performs the following steps when called:

  1. Let number be ? ToNumber(argument).
  2. If number is NaN, +0, -0, +∞, or -∞, return +0.
  3. Let int be the Number value that is the same sign as number and whose magnitude is floor(abs(number)).
  4. Let int32bit be int modulo 2 ** 32.
  5. If int32bit ≥ 2 ** 31, return int32bit - 2 ** 32; otherwise return int32bit.

~, or bitwise NOT, does the same sort of thing, by calling ToInt32 on its operator.

Using x | 0 will remove the decimal part of x (via ToInt32) and flip no bits, so it's as if just the decimal part was removed.

Using ~x will remove the decimal part of x and flip all of its bits. Using ~~x will do the same, but flip the bits twice, so the result is as if all that was done to the original expression was drop the decimal part.

Community
  • 1
  • 1
CertainPerformance
  • 356,069
  • 52
  • 309
  • 320
  • I need to study a lot about numbers in JS, actually I did many times but never get it completely :(. That's the only key to unzip your answer for me. :) – sujeet Apr 26 '20 at 12:27