Math.cbrt cube root would be nice

# Roger Andrews (13 years ago)

A Math.cbrt cube root function would be nice.

This should be more accurate than pow(x,1/3) and should not have a domain error for x<0. Unlike pow(): Math.cbrt(-0) == -0 Math.cbrt(-Infinity) ==

# Roger Andrews (13 years ago)

A Math.cbrt cube root function would be nice.

This should be more accurate than pow(x,1/3) and should not have a domain error for x<0. Unlike pow(): Math.cbrt(-0) == -0

This confuses me. Math.pow(0, 1/3) === Math.pow(-0, 1/3) === 0. Math.cbrt(-0) should most certainly also === 0, since -0 === 0. Was this a typo?

No not a typo; it is the analytically correct handling of -0 in the symmetry relation of an odd function. (See en.wikipedia.org/wiki/Even_and_odd_functions).

Most people don't care about -0, and it is right that -0==0. However -0 is important in Analysis:

  1. it selects the side of a branch cut in the Complex plane (and likely preserves symmetry),
  2. modelling applications often require reflectional symmetry about an axis.

JavaScript already handles -0 well in mathematical functions (but not in strings!): Math.sin(-0) == -0 Strangely IEEE defines and JavaScript conforms: Math.sqrt(-0) ==

# Brendan Eich (13 years ago)

Roger Andrews wrote:

JavaScript already handles -0 well in mathematical functions (but not in strings!):

Strings? Don't use non-e.r. operators (==, !=) or relationals with mixed-type operands. That's just off the Math map.

 Math.sin(-0) == -0

Strangely IEEE defines and JavaScript conforms: Math.sqrt(-0) == -0

Yes, Guy Steele helped us sort this out in ES1 days. Math.atan2(+/-0, +/-0) also has the right sign for the {+/-0, +/-Math.PI} results.

# Roger Andrews (13 years ago)

JavaScript already handles -0 well in mathematical functions (but not in strings!):

Strings? Don't use non-e.r. operators (==, !=) or relationals with mixed-type operands. That's just off the Math map.

I wouldn't dream of it. JavaScript's problem with -0 in string conversion leads to several anomalies. And it does not conform to IEEE754 (as every machine does these days).

Stylistically: (-0).toFixed(0) -> "0"

but (-Number.MIN_VALUE).toFixed(0) -> "-0"

Numerically, with single-element Arrays: +[-0] -> 0

but +[-1] -> -1

Of course +(-0) -> -0

Also -0 is not preserved in a JSON string, even though JSON syntax allows it. Thus simply by transferring data in JSON (without any funny business) one risks an analytical error: JSON.stringify({x: -0}) -> "{"x":0}"

As I said earlier: most people don't care about -0, but it is important in Analysis for:

  1. branch cuts
  2. reflectional symmetry (consider laminar flow at a leading edge).

Before the numerical analysts at IEEE sorted it out, improper -0 was a common mistake in CAD systems since one of the flow lines goes missing, breaking symmetry and failing to establish a boundary. See en.wikipedia.org/wiki/Signed_zero

Would it hurt to do -0 string conversion right? I can't imagine anyone is relying on the current behaviour. I guess this would require a change in the internal toString function, plus changes to Number.prototype.toString and Number.prototype.to****

As for IEEE754 conformance: so near and yet so far ...

Guy Steele helped us sort this out in ES1 days. Math.atan2(+/-0, +/-0) also has the right sign for the {+/-0, +/-Math.PI} results.

Also 1/-0 == -Infinity. And quite right too.

Indeed, JavaScript's mathematical and arithmetic handling of -0 is perfect, and conforms to IEEE754. Much respect and no complaints here. I have checked every ES5 Math function.

# Brendan Eich (13 years ago)

Roger Andrews wrote:

JavaScript already handles -0 well in mathematical functions (but not in strings!):

Strings? Don't use non-e.r. operators (==, !=) or relationals with mixed-type operands. That's just off the Math map.

I wouldn't dream of it. JavaScript's problem with -0 in string conversion leads to several anomalies. And it does not conform to IEEE754 (as every machine does these days).

Stylistically: (-0).toFixed(0) -> "0"

Is this a bug in the spec for toFixed?

15.7.4.5 Number.prototype.toFixed (fractionDigits)

Return a String containing this Number value represented in decimal fixed-point notation with fractionDigits digits after the decimal point. If fractionDigits is undefined, 0 is assumed. Specifically, perform the following steps:

  1. Let f be ToInteger(fractionDigits). (If fractionDigits is undefined, this step produces the value 0).

  2. If f < 0 or f > 20, throw a RangeError exception.

  3. Let x be this Number value.

  4. If x is NaN, return the String "NaN".

  5. Let s be the empty String.

  6. If x < 0, then a. Let s be "-". b. Let x = –x.

Of course, in the language (-0 < 0) is false. See 5.2 Algorithm Conventions:

Mathematical operations such as addition, subtraction, negation, multiplication, division, and the mathematical functions defined later in this clause should always be understood as computing exact mathematical results on mathematical real numbers, which do not include infinities and do not include a negative zero that is distinguished from positive zero. Algorithms in this standard that model floating-point arithmetic include explicit steps, where necessary, to handle infinities and signed zero and to perform rounding. If a mathematical operation or function is applied to a floating-point number, it should be understood as being applied to the exact mathematical value represented by that floating-point number; such a floating-point number must be finite, and if it is +0 or −0 then the corresponding mathematical value is simply 0.

Ouch.

Perhaps toFixed has a quirk we cannot fix at this point. I summon Waldemar and Allen.

# Roger Andrews (13 years ago)

[... -0 in string conversion ...]

(-0).toFixed(0) -> "0"

Is this a bug in the spec for toFixed?

I would say it's deeper than that. It's about JavaScript's philosophy towards -0. Particularly as expressed in the ToString internal function (*). If ToString is fixed then single-element Array conversion and JSON stringification work right.

(*) I.e. steps 2 & 3 of ToString as shown in section 9.8.1 "ToString Applied to the Number Type".

If we accept the need for -0 -- and the precise & correct care taken in Math and arithmetic shows that we do -- then why go off the rails when it comes to string conversion?

In the specific case of Number.prototype.toFixed you could change step 6 to "If x is negative, then", providing the term "negative" is suitably defined. The same goes for Number.prototype.toExponential etc etc.

Note the broken symmetry: ToString is surjective but not injective; ToNumber is both surjective and injective. ToString and ToNumber are not inverses: ToNumber("-0") -> -0

but ToString(-0) -> "0"

Of course, in the language (-0 < 0) is false. See 5.2 Algorithm Conventions.

It is mathematically proper than (-0 < 0) is false. Only if one imposes a Total Order over the set of Number does that expression become true. (IEEE754 has a cmpTotalOrder function which does this, and includes normal and signaling NaNs, and can include NaN payloads if anybody cares).

Am I missing something: Does section 5.2 actually say anything worthwhile at all? Flippantly, it seems to be no more than: "Abstract mathematical arithmetic and functions have exact values, but a finite machine can only deal with floating-point approximations. This standard does limited-precision floating-point not impossible infinite-precision because we cannot wait an eternity for the result and there is not enough energy or matter in the Universe to compute or store an infinitely precise result. Intermediate results will be rounded. Buy a textbook on Numerical Analysis, or take your chances."