Skip to content

Commit

Permalink
extended readme and docs
Browse files Browse the repository at this point in the history
  • Loading branch information
mristin committed Jun 9, 2019
1 parent 3c5e0c7 commit fd9d922
Show file tree
Hide file tree
Showing 2 changed files with 52 additions and 4 deletions.
5 changes: 2 additions & 3 deletions docs/source/cpp_specifics.rst
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}


Expand Down
51 changes: 50 additions & 1 deletion docs/source/go_specifics.rst
Original file line number Diff line number Diff line change
Expand Up @@ -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
Implementation Details
----------------------
Numbers
^^^^^^^
The standard `encoding/json <https://golang.org/pkg/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 <https://ieeexplore.ieee.org/document/4610935>`_, ``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 <https://golang.org/pkg/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.

0 comments on commit fd9d922

Please sign in to comment.