Subject: [Json] Minus Zero

From: Christian Zangl <[email-masked]>
Date: Sun, 19 Jun 2016 22:41:20 +0200

The RFC does not mention this but most (all?) JavaScript JSON libraries 
stringify -0 as "0" (including https://github.com/douglascrockford/JSON-js).

Should this be included?

---

From: Carsten Bormann <[email-masked]>
Date: Sun, 19 Jun 2016 23:09:09 +0200

Christian Zangl wrote:
> stringify -0 as "0" (including
> https://github.com/douglascrockford/JSON-js).

Which RFC?

-0 evaluates to 0 in most programming languages (two's complement
integer arithmetic).
-0.0 of course is something different (floating point arithmetic
distinguishes positive and negative zero).
I would expect a decent JSON implementation to serialize this number as
"-0.0" for maximum interoperability with recipients that internalize
integer numbers as integers.

The JSON interchange format does not call out the difference between
integers and floating point numbers, because it only deals in the
decimal representations of numbers, but many programming languages do.

JavaScript doesn't have that distinction in its number system, but the
quirks following from that fact are less relevant for the JSON standard
than for its JavaScript-constrained profile I-JSON, RFC 7493.
That RFC is indeed missing mention of this particular quirk in its
section 2.2, where that information might possibly help.

Grüße, Carsten

>> JSON.dump([0])
=> "[0]"
>> JSON.dump([-0])
=> "[0]"
>> JSON.dump([0.0])
=> "[0.0]"
>> JSON.dump([-0.0])
=> "[-0.0]"

>> JSON.load("[-0.0]")
=> [-0.0]
>> JSON.load("[0.0]")
=> [0.0]
>> JSON.load("[0]")
=> [0]
>> JSON.load("[-0]")
=> [0]

---

From: Anders Rundgren <[email-masked]>
Date: Mon, 20 Jun 2016 21:23:05 +0200

> stringify -0 as "0" (including https://github.com/douglascrockford/JSON-js).

Serialization is not really a part of the JSON RFC.

ECMAScript V6 (ES6) is is the only normative JSON serialization reference.
Some JSON implementations are even incompatible with ES6 even for serialization of strings!
.NET and GO are currently being updated.

Serialization of floating point numbers is another thing, currently only Chrome, Safari, Firefox, node.js-V8, and my own Java implementation seem to follow ES6.

Using ES6 there is no such thing as -0 or -0.0 during serialization since the algorithm is designed to produce the shortest correct representation which is a single zero digit.

Anders

---

From: Carsten Bormann <[email-masked]>
Date: Mon, 20 Jun 2016 21:52:34 +0200

> Serialization is not really a part of the JSON RFC.

Well, it defines a format that can be used to serialize the JSON data
model, but is not specific about corner cases in that data model.

> ECMAScript V6 (ES6) is is the only normative JSON serialization reference.

But that is only relevant to ES6 implementations; we don't have to care.

> [...]

(Attempts to get everybody else to follow the ES6 rules are generally
regarded as quixotic; see below for an example why.)

> Using ES6 there is no such thing as -0 or -0.0 during serialization
> since the algorithm is designed to produce the shortest correct
> representation which is a single zero digit.

I don't think anybody who cares about use of floating point numbers in
numerics would agree that this representation of -0.0 is "correct".  But
then representing all infinites (all of +Infinity, -Infinity, and NaN)
as "null" doesn't indicate that numerical usefulness was high on the
agenda of the ES6 specifiers.

Grüße, Carsten

---

From: Christian Zangl <[email-masked]>
Date: Mon, 20 Jun 2016 22:55:41 +0200

> But that is only relevant to ES6 implementations; we don't have to care.

OK, but since RFC 7159/6. already mentions "[..] Note that when such 
software is used, numbers that are integers and are in the range 
[-(2**53)+1, (2**53)-1] are interoperable in the sense that 
implementations will agree exactly on their numeric values," couldn't 
the 0/-0 case be mentioned as well?

---

From: Anders Rundgren <[email-masked]>
Date: Tue, 21 Jun 2016 17:21:05 +0200

software is used, numbers that are integers and are in the range
[-(2**53)+1, (2**53)-1] are interoperable in the sense that implementations
will agree exactly on their numeric values," couldn't the 0/-0 case be
mentioned as well?

Implementstions do NOT agree on floating point serialization.  Neither text
(like E or e), leading zeroes or even values are to be counted on.

Anders

---

From: John Cowan <[email-masked]>
Date: Tue, 21 Jun 2016 11:42:45 -0400

> (like E or e), leading zeroes or even values are to be counted on.

Disagreement on the lexical details of production does not mean disagreement
on interpretation, which is what is at stake here.  Nobody supposes that
10, 1e1, 1E1, 10.0, 10.00 mean different things.  The same is not true for
0.0 and -0.0.

-- 
John Cowan          http://www.ccil.org/~cowan        [email-masked]
Nobody expects the RESTifarian Inquisition!  Our chief weapon is
surprise ... surprise and tedium  ... tedium and surprise ....
Our two weapons are tedium and surprise ... and ruthless disregard
for unpleasant facts....  Our three weapons are tedium, surprise, and
ruthless disregard ... and an almost fanatical devotion to Roy Fielding....

---

From: Anders Rundgren <[email-masked]>
Date: Tue, 21 Jun 2016 19:02:56 +0200

> 10, 1e1, 1E1, 10.0, 10.00 mean different things.  The same is not true for

Apparently the ES6 folks consider IEEE 0.0 and -0.0 equal during JSON serialization.
This is probably a reasonable conclusion since non-normalized numbers are treated differently.
It is also better aligned with integers.

In order to make anything else JSON would need separate integer and floating point types.

Anders

---

From: John Cowan <[email-masked]>
Date: Tue, 21 Jun 2016 16:41:51 -0400

> Apparently the ES6 folks consider IEEE 0.0 and -0.0 equal during JSON

In effect that means that -0, like NaN and Infinity and -Infinity, can't
be serialized correctly as JSON.  But instead of being serialized as null,
it's serialized the same as 0.

> In order to make anything else JSON would need separate integer and

I don't understand that.  JavaScript's internal model of numbers already
includes -0.0 (e.g. the value of the expression 1/(-1*0) is -Infinity).
The node.js and Chrome REPLs will print -0 in appropriate circumstances
(whereas the Rhino and Edge REPLs will not).

-- 
John Cowan          http://www.ccil.org/~cowan        [email-masked]
But the next day there came no dawn, and the Grey Company passed on
into the darkness of the Storm of Mordor and were lost to mortal sight;
but the Dead followed them.          --"The Passing of the Grey Company"

---

From: Carsten Bormann <[email-masked]>
Date: Tue, 21 Jun 2016 23:48:10 +0200

> (whereas the Rhino and Edge REPLs will not).

The REPLs will, thankfully, but JSON.stringify(-0) (which is the JSON
implementation defined in more recent JavaScripts) acts broken as
designed (ES5.1 15.2.3 second list number 9a with 9.8.1 number 2; ES6
24.3.2.1 number 10a with 7.1.12.1 number 2).

Grüße, Carsten

---

From: Anders Rundgren <[email-masked]>
Date: Wed, 22 Jun 2016 17:37:43 +0200

> it's serialized the same as 0.

I would have done the same.  -0.0 is as I understand as close to zero you can get.
The need for separating the -0.0 and 0.0 in real-world applications is probably 0.0 :-)

If full IEEE notation is needed "string" representation seems to be the only way ahead.

> (whereas the Rhino and Edge REPLs will not).

I just referred to the fact that -0 is not a useful way of serializing an integer,
it only makes (some) sense in an IEEE floating point world.

By using a single type for holding "Number", the designers had to do some compromises.

In my java-based JSON parser I have added additional checks so that if you expect an
integer using a getInt() access method, "19.0" would generate an exception.  Serializing
integers above abs((2**53)-1) also generates an exception.

Anders

---

From: John Cowan <[email-masked]>
Date: Wed, 22 Jun 2016 16:31:39 -0400

Anders Rundgren scripsit:

> I would have done the same.  -0.0 is as I understand as close to zero
> you can get.  The need for separating the -0.0 and 0.0 in real-world
> applications is probably 0.0 :-)

Well, if you make use of affine infinity (that is, you distinguish
Infinity from -Infinity), then you need two kinds of zeros, positive
and negative.  They are numerically equal, but are arithmetically
distinguishable.

> I just referred to the fact that -0 is not a useful way of serializing

True.

-- 
John Cowan          http://www.ccil.org/~cowan        [email-masked]
Economists were put on this planet to make astrologers look good.
        --Leo McGarry