MarkLogic Server and the decimal type implementation
11 May 2017 10:40 AM
Introduction: the decimal type
Decimal type has been implemented for very specific requirements, decimals have about a dozen more bits of precision than doubles but take up more memory and arithmetic operations over them are much slower.
Use the double where possible
Unless you have a specific requirement to use a Decimal data type, in most case it's better and faster to use the double data type to represent large numbers.
Specific details about the decimal data type
If you still want or need to use a decimal data type below are its limitations and details on how exactly it is implemented in MarkLogic Server:
The MarkLogic implementation of xs:decimal representation is designed to meet the XQuery specification requirements to provide at least 18 decimal digits of precision. In practice, up to 19 decimal digits can be represented with full fidelity.
A decimal number is represented inside MarkLogic with 64 binary bits of digits and an additional 64 bits of sign and a scale (specifies where the decimal point is).
-18446744073709551615 to 18446744073709551615
Any operation producing number smaller or bigger than this range will result in XDMP-DECOVRFLW error (decimal overflow)
It has a floating scale.
-20 to 0
So you can only represent numbers between 1 * (2^-64) and 18446744073709551615
It can represent 64 bit unsigned integers with full fidelity.
The division algorithm on Linux in particular does convert to an 80-bit binary floating point representation to calculate reciprocals - which can result in binary rounding errors. Other arithmetic algorithms work solely in base 10.
Overflow: Number is too big or small to represent
It has a representation with 64 bits of digits, a sign, and a base 10 negative exponent (fixed to range from -20 to 0). So the value is calculated like this:
On disk, for example in triple indexes, it's not a fixed size as it uses integer compression. At maximum, the decimal scalar type consumes 16 bytes per value: eight bytes of digits, four bytes of sign, and four bytes of scale. It is not space efficient but it keeps the digits aligned on eight-byte boundaries.