IEEE 754 has a precise meaning for sign bit. JavaScript’s Math falls
short on and . This is a shortcoming of a "batteries included"
approach to language design.
Correctly obtaining the sign bit of a Number in JavaScript is somewhat
unintuitive: the naïve x approach fails if x is because and compare equal to each other.
One can instead rely on division by zero returning one of or : . This now has the interesting caveat of returning if x was . It’s also highly counter-intuitive.
JavaScript aficionado will know that Object will return when x is but not when it’s . This is surprising for developers who are
more numerics-oriented than object-—dare I say prototype-?—oriented. These
developers just want the sign bit, IEEE 754 has a very precise definition of
what the sign bit is, and why can’t JavaScript just give them the sign bit?
This issue has been discussed previously but was never addressed. We believe that this proposal can fix this oft-encountered problem once and for all.
1. Revision History
-
Presented at the 2017-01 TC39 meeting and moved to Stage 1.
2. Background
2.1. IEEE 754
[IEEE754] section 5.5.1 defines sign bit operations. These operations are quiet-computational operations which only affect the sign bit of the arithmetic format. The operations treat floating-point numbers and NaNs alike, and signal no exception. As defined, they may propagate non-canonical encodings.
The following operations are defined:
-
copy -
negate -
abs
2.2. C / C++
[C] and [Cpp] define signbit in and respectively. It
returns a nonzero value if and only if the sign of its argument value is
negative. The signbit macro reports the sign of all values, including
infinities, zeros, and NaNs.
2.3. Go
[Go]'s math package defines Signbit as if x is negative or negative
zero. While the specification is silent on NaN, the implementation clearly extracts the
sign bit regardless of NaN-ness.
2.4. Math. sign( x)
JavaScript provides Math which is specified as follows:
Returns the sign of the x, indicating whether x is positive, negative or zero.
If
xis, the result isNaN .NaN If
xis, the result is- 0 .- 0 If
xis, the result is+ 0 .+ 0 If
xis negative and not, the result is- 0 .- 1 If
xis positive and not, the result is+ 0 .+ 1
This falls short when dealing with and since these values both compare
equal.
3. Proposal
Given existing precedent as well as common hardware support, we propose adding Math to JavaScript as follows.
3.1. Math. signbit( x)
Returns whether the sign bit of x is set.
-
If
xis, the result isNaN .false -
If
xis, the result is- 0 .true -
If
xis negative, the result is.true -
Otherwise, the result is
.false
Note: The "Function Properties of the Math Object" section already states:
"Each of the following Math object functions applies the ToNumber abstract
operation to each of its argument."
3.2. Alternatives
This proposal makes decisions which TC39 may want to consider modifying:
-
Coercison
ToNumber. -
The return type is Boolean.
-
NaN is equivalent to a positive number.