Skip to content

cyberphone/I-JSON-Number-System

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

27 Commits
 
 

Repository files navigation

Extended Numeric Data Types Compliant with I-JSON

I-JSON [RFC7493] defines rules which enable interoperability between between different implementations. Although useful, many applications depend on extended numeric data which currently is dealt with in non-standard ways. This document describes some of the more common variants, with the goal of eventually establishing some kind of standard, be it de-facto or real.

The Problem in a Nutshell

The following JSON object highlights some of the issues with JSON numbers:

{
  "giantNumber": 1.4e+9999,
  "payMeThis": 26000.33,
  "int64Max": 9223372036854775807
}
  • giantNumber does not generally parse but could still be usable in certain contexts
  • payMeThis is probably not meant to be processed by a system based on traditional floating point due to potential rounding errors
  • int64Max parses in all JSON systems but loses precision using ECMAScript's JSON.parse()

Core Extension Mechanism

Since I-JSON numbers are constrained by IEEE-754 double precision, extended numeric data types must in this specification be enclosed within double quotes, i.e. have JSON String syntax, permitting basic parsing and serialization of extended data types by virtually any JSON tool:

{
  "giantNumber": "1.4e+9999"
}

Recognizing and Processing Extended Numeric Data Types

A remaining issue is how a JSON parser can know how to recognize and process extended numeric data types. Fortunately, there are multiple solutions for that. Below is a programmatic variant (here expressed in ECMAScript). relying on name conventions between sender and receiver:

var obj = JSON.parse('{"giantNumber": "1.4e+9999"}');
var biggie = new BigNumber(obj.giantNumber);

In a declarative system, data types are usually resolved automatically like in this Java sample:

class MyObject {
    String type;
    BigInteger serialNumber;
 }

Extended Numeric Data Types

TypeDescriptionRange       JSON Syntax *      
LongSigned 64-bit integer-9223372036854775808 to 92233720368547758070|-?[1-9][0-9]*
UlongUnsigned 64-bit integer0 to 184467440737095516150|[1-9][0-9]*
BigIntegerArbitrary large signed integer-Arbitrary to Arbitrary0|-?[1-9][0-9]*
BigDecimalArbitrary large decimal number-Arbitrary to Arbitrary-?[0-9]+(\.[0-9]+)?(e(-|\+)[0-9]+)?
MoneyDecimal number expressing money-Sufficient to Sufficient-?[1-9][0-9]*\.[0-9]+

* Minus the double quotes.

Sufficient denotes earthly monetary sums.

Existing Solutions

A few existing solutions have been investigated.

Java JSON-B

JSON-B currently uses Adaptive Notation where the actual value determines if it is to be serialized as a JSON Number or be embedded in a JSON String:

{
  "BigDecimal.large": "1E+999",
  "BigDecimal.small": 1,
  "BigInteger.large": "240777489003222785532321",
  "BigInteger.small": 1,
  "Long.large": 9223372036854775807,
  "Long.small": 1
}

This scheme is with the exception of "Long.large" compatible with JSON.parse();

Json.NET

Json.NET doesn't seem to have any global option governing number serialization. The defaults are:

{
  "Decimal.large": 3777777447789999999445.678997,
  "Decimal.small": 1.0,
  "BigInteger.large": 240777489003222785532321,
  "BigInteger.small": 1,
  "Long.large": 9223372036854775807,
  "Long.small": 1
}

This is not compliant with JSON.parse();

bignumber.js

The NPM https://www.npmjs.com/package/bignumber.js relies on strings for BigNumber JSON serialization and parsing.

W3C Payment Request

The W3C Payment Request API defines a monetary amount as

dictionary PaymentCurrencyAmount {
    required DOMString currency;
    required DOMString value;
};

where value is a decimal number. The DOMString declarator means that the value is to be expressed as a JSON/ECMAScript String.

Open Banking UK

The following JSON extract from the Open Banking API shows that monetary amounts are expressed as decimal numbers enclosed in strings:

{
  "amount": "259.99",
  "currency": "GBP"
}

Twitter

The Tweet Object shows the downside of not having a unified way of dealing with big numbers:

{
  "created_at": "Thu Apr 06 15:24:15 +0000 2017",
  "id": 850006245121695744,
  "id_str": "850006245121695744",
  "text": "This is what I'm saying :-)",
  "user": {},  
  "entities": {}
}

V0.12

About

Extended Numeric Data Types compliant with I-JSON

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published