Skip to content

JSON emitting: improve handling of nan, inf and some floats#574

Merged
biojppm merged 1 commit intomasterfrom
fix/535_json_inf
Mar 3, 2026
Merged

JSON emitting: improve handling of nan, inf and some floats#574
biojppm merged 1 commit intomasterfrom
fix/535_json_inf

Conversation

@biojppm
Copy link
Copy Markdown
Owner

@biojppm biojppm commented Mar 2, 2026

For example, the tree

{
  inf: [inf, .inf, .Inf, .INF, -inf, -.inf, -.Inf, -.INF],
  nan: [nan, .nan, .NaN, .NAN],
  dot: [.1, 1., .2e2, 10., -.2, -2.],
  zero: [10, 01],
  normal: [0.1, 0.2e3, 4.e5],
}

is now emitted to JSON as:

{
  "inf": [".inf",".inf",".inf",".inf","-.inf","-.inf","-.inf","-.inf"],
  "nan": [".nan",".nan",".nan",".nan"],
  "dot": [0.1,1.0,0.2e2,10.0,-0.2,-2.0],
  "zero": [10,"01"],
  "normal": [0.1,0.2e3,4.e5]
}

Previously, some inf and nan cases were emitted without quotes. Note also the added zeroes for some floats, eg .1 or -2., which turn into 0.1 and -2.0 in JSON.

I tried using "8e888" for inf as suggested in #312 but this value cannot be parsed by to_chars() (see proof in added tests), which prevents roundtrip equivalence. So I opted for a sensible ".inf" string for all inf cases.

Fixes #312
Fixes #535

@biojppm
Copy link
Copy Markdown
Owner Author

biojppm commented Mar 2, 2026

@davidrudlstorfer @captain-yoshi @sebproell Tagging you here because of #535 and #312 .

Please take a look at this PR; IMO it addresses the problems discussed in those issues.

As I said above (and you can verify in the tests added in this PR), 8e888 cannot be used to signify infinity because fast_float to_chars() cannot parse this, which prevents roundtrip equivalence. I did not look further than that into this aspect.

Other than that, the proposed JSON strings .nan, .inf and -.inf can be used say in JS to check for these special values, and ryml deserializes them to their proper values as well.

@codecov
Copy link
Copy Markdown

codecov bot commented Mar 2, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 97.57%. Comparing base (8ca4a03) to head (e721250).
⚠️ Report is 2 commits behind head on master.

Additional details and impacted files
@@            Coverage Diff             @@
##           master     #574      +/-   ##
==========================================
- Coverage   97.61%   97.57%   -0.04%     
==========================================
  Files          46       46              
  Lines       13651    13677      +26     
==========================================
+ Hits        13326    13346      +20     
- Misses        325      331       +6     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@davidrudlstorfer
Copy link
Copy Markdown
Contributor

@biojppm thanks for the nice fix and also big thanks for the tag. Nice that this is now working as expected :)

(@gilrrei now we can revert 4C-multiphysics/fourcipp#78 and 4C-multiphysics/fourcipp#85)

For example, the tree
  ```yaml
  {
    inf: [inf, infinity, .inf, .Inf, .INF, -inf, -infinity, -.inf, -.Inf, -.INF],
    nan: [nan, .nan, .NaN, .NAN],
    dot: [.1, 1., .2e2, 10., -.2, -2.],
    zero: [10, 01],
    normal: [0.1, 0.2e3, 4.e5],
  }
  ```
is now emitted to JSON as:
  ```json
  {
    ".inf": [".inf",".inf",".inf",".inf","-.inf","-.inf","-.inf","-.inf","-.inf","-.inf"],
    ".nan": [".nan",".nan",".nan",".nan"],
    "dot": [0.1,1.0,0.2e2,10.0,-0.2,-2.0],
    "zero": [10,"01"],
    "normal": [0.1,0.2e3,4.e5]
  }
  ```
Previously, some inf and nan cases were emitted without quotes; now they are all emitted with the fixed strings `.nan` and `.inf`, which helps in cases where the JSON may be loaded in JavaScript. Note also the added zeroes for some floats, eg `.1` or `-2.` turning into `0.1` and `-2.0`.

I tried using "8e888" for int as suggested in #312 but this value cannot be parsed by to_chars() (see proof in added tests), which prevents roundtrip equivalence. So I opted for a sensible `".inf"` string for all inf cases.
@biojppm biojppm force-pushed the fix/535_json_inf branch from a33f75e to e721250 Compare March 3, 2026 20:27
@biojppm biojppm merged commit ca56fd7 into master Mar 3, 2026
261 of 265 checks passed
@biojppm biojppm deleted the fix/535_json_inf branch March 3, 2026 23:28
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.

Edge cases producing invalid JSON when emitting a tree read from YAML Add dquotes around inf and nan when serializing to json

2 participants