javascriptnegative-zero

In String.prototype.slice(), should .slice(0,-0) and .slice(0,+0) output the same result?


I came across this quirk while trying to optimise string pluralisation in a game of code golf. I had the idea to write strings as plurals and then use substr to cut the last character off, conditionally:

var counter = 1;
var myText = counter + " units".substr(0, 6-(counter===1));

It's fine - it does what I wanted. But looking at the MDN docs for String.prototype.slice(), I thought I had found a way to make it even shorter, by using passing negative zero as the second argument to the function. From the docs:

endSlice

Optional. The zero-based index at which to end extraction. If omitted, slice() extracts to the end of the string. If negative, it is treated as sourceLength + endSlice where sourceLength is the length of the string (for example, if endSlice is -3 it is treated as sourceLength - 3).

var myText = counter + " units".slice(0,-(counter===1));

This evaluates to .slice(0,-1) when counter is equal to 1, which would chop the last letter from the string, or it would otherwise evaluate to .slice(0,-0), which according to the docs should mean 0 characters were subtracted from the length of the string being operated upon.

As it happens, -0 is treated the same as +0 by String.prototype.slice. I wondered if this was a convention, to treat -0 as being the same as +0 (I know, for instance, -0 === +0 evaluates to true). I thought to look at String.prototype.substr, but +0 and -0 are supposed to be handled the same way in that function.

Does anyone have any greater insight into this? Is there some basic convention in the language design that states that, while signed zero is a language feature, it should be ignored, except in certain scenarios (like 1/-0)?

tl;dr I'm salty that I can't make jokes about winning code golf by slicing.


Solution

  • From a mathematical perspective there is no negative zero. Positive is any number greater than zero, and negative is any number smaller than zero. Zero is neither of those. So I guess the behaviour you described is correct.

    A real number may be either rational or irrational; either algebraic or transcendental; and either positive, negative, or zero.

    https://en.wikipedia.org/wiki/Real_number

    Although, because in programming we work with floating point numbers, which are an approximation of real numbers, there is a concept of -0, which could be a representation of a negative number too close to zero to be represented otherwise - http://www.johndcook.com/blog/2010/06/15/why-computers-have-signed-zero/


    Regarding your javascript, you could write it as:

    var counter = 1;
    var myText = counter + " unit" + (counter > 1 ? "s" : "");