From fd9d922d61f169a8111731aedf7be76a6a70c320 Mon Sep 17 00:00:00 2001 From: Marko Ristin Date: Sun, 9 Jun 2019 10:20:18 +0200 Subject: [PATCH] extended readme and docs --- docs/source/cpp_specifics.rst | 5 ++-- docs/source/go_specifics.rst | 51 ++++++++++++++++++++++++++++++++++- 2 files changed, 52 insertions(+), 4 deletions(-) diff --git a/docs/source/cpp_specifics.rst b/docs/source/cpp_specifics.rst index 1510b2e..7d4110c 100644 --- a/docs/source/cpp_specifics.rst +++ b/docs/source/cpp_specifics.rst @@ -94,9 +94,8 @@ You can seamlessly access the properties and iterate over aggregated types: for (const book::address::Person& maintainer : pipeline.maintainers) { std::cout << maintainer.full_name - << " (address: " - << maintainer.address.text - << ")" << std::endl; + << " (address: " << maintainer.address.text << ")" + << std::endl; } diff --git a/docs/source/go_specifics.rst b/docs/source/go_specifics.rst index ca751f3..8c4e452 100644 --- a/docs/source/go_specifics.rst +++ b/docs/source/go_specifics.rst @@ -87,4 +87,53 @@ Assuming the deserialized ``pipeline``, you serialize it back into a JSONable var jsonable map[string]interface{} jsonable, err = address.PipelineToJSONable(pipeline) -TODO: add considerations about the specific fields \ No newline at end of file +Implementation Details +---------------------- +Numbers +^^^^^^^ +The standard `encoding/json `_ package +uses double-precision floating-point numbers (``float64``) to represent both +floating-point and integral numbers. Mapry-generated Go code follows this +approach and assumes that all numbers are represented as ``float64``. This +assumption has various implications on what numbers can be represented. + +The set of representable floating-point numbers equals thus that of +``float64``, namely -1.7976931348623157e+308 to 1.7976931348623157e+308 with the +smallest above zero being 2.2250738585072014e-308. Hence Mapry also represents +floating points as ``float64``. + +Unlike floating-point numbers, which are simply mirroring internal and JSONable +representation, Mapry represents integers as ``int64`` which conflicts with +JSONable representation of numbers as ``float64``. Namely, according to +`IEEE 754 standard `_, ``float64`` +use 53 bits to represent digits and 11 bits for the exponent. This means that +you can represent all the integers in the range [-2^53, 2^53] (2^53 == +9,007,199,254,740,992) without a loss of precision. However, as you cross 2^53, +you lose precision and the set of representable integers becomes sparse. For +example, 2^53 + 7 is 9,007,199,254,740,999 while it will be represented as +9,007,199,254,741,000.0 (2^53 + 8) in ``float64``. Hence, you can precisely +represent 2^53 + 8, but not 2^53 + 7, in your JSONable. + +Unfortunately, most JSON-decoding packages (*e.g.,* +`encoding/json `_) will silently ignore +this loss of precision. For example, assume you supply a string encoding a JSON +object containing an integer property set to 2^53 + 7. You pass this string +through ``encoding/json`` to obtain a JSONable and then pass it on to Mapry for +further parsing. Since Mapry does not directly operate on the string, but on an +intermediate JSONable representation (which represents numbers as ``float64``), +your Mapry structure ends up with integer representations that diverges from the +original string. + +Note that this is a practical problem and not merely a theoretical one. For +example, unique identifiers are often encoded as 64-bit integers. If they are +generated randomly (or use 64-bits to encode extra information *etc.*) you +should represent them in JSON as strings and not numbers. Otherwise, you will +get an invalid unique identifier once you decode the JSON. + +Furthermore, Mapry representation of integers with 64-bits restricts the range +of representable integers to [-2^64, 2^64 - 1] (-9,223,372,036,854,775,808 to +9,223,372,036,854,775,807). In contrast, JSONable representation uses +``float64`` and hence can represent the above-mentioned wider range of +``float64``. Due to this difference in representations, Mapry-generated code +will raise an error if a number needs to be parsed into an integer that is out +of 64-bit range.