Skip to content

Keep 16 fractional digits for xsd:decimal and fix large-value parsing - #83

Open
MathiasVDA wants to merge 2 commits into
DataTreehouse:mainfrom
MathiasVDA:fix/decimal-scale-16
Open

MathiasVDA wants to merge 2 commits into
DataTreehouse:mainfrom
MathiasVDA:fix/decimal-scale-16

Conversation

@MathiasVDA

Copy link
Copy Markdown

Requested by Mathias

Part of #70 (the value side; the padded Turtle output reported there is not changed here).

Before:

  • xsd:decimal literals with more than 12 fractional digits were truncated when read: 760.3865996838672 became 760.386599683867, and 0.0000000000001 became 0.
  • Large decimals were corrupted: rust_decimal's 96-bit mantissa cannot hold them at the default scale, and rescale() silently shifted the decimal point (9999999999999.5 became 999999999999.95). At scale 12 this starts at about 10^16.
  • STR() on a decimal returned the fixed-scale string with padding zeros ("1.500000000000").

After:

  • 16 fractional digits are kept, which is what XSD 1.1 Part 2 §5.4 requires of minimally conforming processors (i < 10^16, k ≤ 16).
  • Values keep their value up to 22 integer digits (precision 38 minus scale 16). A value with more integer digits raises a parse error instead of being silently changed.
  • STR() returns the canonical form, trimmed like the N-Triples writer already does: "1.5", "798", "-12.34".

How:

  • default_decimal_scale() goes from 12 to 16.
  • parse_xsd_decimal parses the digits straight into the i128 mantissa instead of going through rust_decimal.
  • str_function trims trailing zeros (and a trailing .) for xsd:decimal.

Trade-off: the largest supported integer part shrinks from 26 to 22 digits. If you prefer to keep scale 12, the parser and STR() changes still stand on their own.

Tests: py_maplib/tests/test_decimal_precision.py (round-trip of 13 and 16 fractional digits, large values, canonical STR()). The existing basics, JSON, HDT, read/write, RDF parser and custom-function tests pass.

🤖 Generated with Claude Code

MathiasVDA and others added 2 commits October 4, 2026 09:03
XSD 1.1 Part 2 5.4 requires support for decimals with up to 16 fractional
digits. With a scale of 12, values such as 760.3865996838672 were truncated
when read. Refs DataTreehouse#70.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…decimals

rust_decimal's 96-bit mantissa cannot hold large values at the default scale,
and rescale() silently shifted the decimal point (9999999999999.5 became
999999999999.95). Parse the digits into the i128 mantissa directly and
reject values with more integer digits than the type allows.

STR() on a decimal cast the fixed-scale value to a string with padding zeros
("1.5000000000000000"). Trim it to the canonical form, as the N-Triples writer
does. Refs DataTreehouse#70.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant