Math.signbit

Stage 1: Proposal,

Author:
(Apple)
Source:
github.com/jfbastien/papers/blob/master/source/Math.signbit.bs

Abstract

IEEE 754 has a precise meaning for sign bit. JavaScript’s Math.sign falls short on -0.0 and +0.0. 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 < 0 approach fails if x is -0.0 because 0.0 and -0.0 compare equal to each other.

One can instead rely on division by zero returning one of -Infinity or +Infinity: 1.0 / x < 0. This now has the interesting caveat of returning NaN if x was NaN. It’s also highly counter-intuitive.

JavaScript aficionado will know that Object.is(-0, x) will return true when x is -0 but not when it’s 0. 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

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:

2.2. C / C++

[C] and [Cpp] define signbit in <math.h> and <cmath> respectively. It returns a nonzero int 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 true 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

JavaScript provides Math.sign which is specified as follows:

Returns the sign of the x, indicating whether x is positive, negative or zero.

This falls short when dealing with -0 and +0 since these values both compare equal.

3. Proposal

Given existing precedent as well as common hardware support, we propose adding Math.signbit to JavaScript as follows.

3.1. Math.signbit(x)

Returns whether the sign bit of x is set.

  1. If n is NaN, the result is false.

  2. If n is -0, the result is true.

  3. If n is negative, the result is true.

  4. 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:

References

Informative References

[C]
Programming Languages — C. URL: http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1570.pdf
[Cpp]
Programming Languages — C++. URL: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3797.pdf
[Go]
The Go Programming Language — Package math. URL: https://golang.org/pkg/math/
[IEEE754]
IEEE 754-2008. URL: https://standards.ieee.org/findstds/standard/754-2008.html