I used to think that all numbers are stored in computers in 2’s complement format. And there is no -0 in 2’s complement. But in IEEE754, there are both +0 and -0. And I read that in JavaScript, all numbers are IEEE754. So now I am confused. What’s more, in JavaScript, ~a = -a -1. I used to think it was caused by the change of 2’s complement of number a. But if every number in JavaScript is stored as IEEE754, how can we convert it as 2’s complement?
Asked
Active
Viewed 598 times
4
-
2's complement is how *integer* values are represented. Floating-point values are another native format, and the values represent binary exponential notation. – Pointy Nov 23 '18 at 18:39
-
@Pointy Thanks. So is it correct that in JavaScript, integer values are also represented as floating-point values, which are represented as IEEE754? – T.T Nov 23 '18 at 18:42
-
Well JavaScript numbers are always double-precision floating point values. In the course of evaluating subexpressions with boolean operators like `~` or `|`, 32-bit integer values are used, but as soon as a value is saved in a variable or object property it's always a floating point value. – Pointy Nov 23 '18 at 18:46
-
"So is it correct that in JavaScript, integer values are also represented as floating-point values" – No. there *are no integers* in JavaScript. – Jörg W Mittag Nov 23 '18 at 18:49
-
@Pointy So with ~ operator, the 32-bit integer values used are calculated from the the original double-precision floating values, right? – T.T Nov 23 '18 at 18:52
-
@JörgWMittag But how can it make ~a = -a+1 with IEEE754? – T.T Nov 23 '18 at 18:54
-
Yes, exactly. The intermediate integer value will be converted back to floating point whenever an ordinary math operation is done with "normal" numbers. – Pointy Nov 23 '18 at 18:54
-
@Pointy Now everything makes sense to me. Thanks! – T.T Nov 23 '18 at 18:55
-
3@JörgWMittag: The text you quoted says “integer values.” JavaScript does have integer values. It uses an IEEE-754 floating-point **type** to represent numbers, and its format is capable of representing many integer **values**. – Eric Postpischil Nov 24 '18 at 01:28
1 Answers
4
JavaScript cheats: It represents numbers using the IEEE-754 basic 64-bit binary floating-point format but converts them to 32-bit integers for bitwise operations and then converts them back.
JavaScript is an implementation of ECMAScript. The ECMAScript 2018 Language Specification (9th edition, June 2018) specifies the unary ~
operator in clause 12.5.8 (shown as 12.5.10 in the table of contents but 12.5.8 in the text!). The relevant part is:
UnaryExpression : ~ UnaryExpression 1. Let expr be the result of evaluating UnaryExpression. 2. Let oldValue be ? ToInt32(? GetValue(expr)). 3. Return the result of applying bitwise complement to oldValue. The result is a signed 32-bit integer.
The ToInt32
operation truncates the number to an integer (removing any fraction part, rounding toward zero) and then maps the number to the interval [−231, +231) modulo 232.

Eric Postpischil
- 195,579
- 13
- 168
- 312