Title: Upstream Bug: JsonNumber.of(double) hardcodes decimalOffset causing toLong to fail · Issue #118 · simbo1905/java.util.json.Java21 · GitHub
Open Graph Title: Upstream Bug: JsonNumber.of(double) hardcodes decimalOffset causing toLong to fail · Issue #118 · simbo1905/java.util.json.Java21
X Title: Upstream Bug: JsonNumber.of(double) hardcodes decimalOffset causing toLong to fail · Issue #118 · simbo1905/java.util.json.Java21
Description: Summary The JsonNumber.of(double) factory method has a bug where it hardcodes decimalOffset=0 and exponentOffset=0 when creating the JsonNumberImpl. This causes toLong() to fail for integral doubles like 123.0. Root Cause In JsonNumber.j...
Open Graph Description: Summary The JsonNumber.of(double) factory method has a bug where it hardcodes decimalOffset=0 and exponentOffset=0 when creating the JsonNumberImpl. This causes toLong() to fail for integral double...
X Description: Summary The JsonNumber.of(double) factory method has a bug where it hardcodes decimalOffset=0 and exponentOffset=0 when creating the JsonNumberImpl. This causes toLong() to fail for integral double...
Opengraph URL: https://github.com/simbo1905/java.util.json.Java21/issues/118
X: @github
Domain: patch-diff.githubusercontent.com
{"@context":"https://schema.org","@type":"DiscussionForumPosting","headline":"Upstream Bug: JsonNumber.of(double) hardcodes decimalOffset causing toLong to fail","articleBody":"## Summary\n\nThe `JsonNumber.of(double)` factory method has a bug where it hardcodes `decimalOffset=0` and `exponentOffset=0` when creating the `JsonNumberImpl`. This causes `toLong()` to fail for integral doubles like `123.0`.\n\n## Root Cause\n\nIn `JsonNumber.java` line 117:\n```java\nstatic JsonNumber of(double num) {\n if (!Double.isFinite(num)) {\n throw new IllegalArgumentException(\"Not a valid JSON number\");\n }\n var str = Double.toString(num);\n return new JsonNumberImpl(str.toCharArray(), 0, str.length(), 0, 0);\n // ^^^^^ BUG: hardcoded offsets\n}\n```\n\nFor `Double.toString(123.0)` which returns `\"123.0\"`:\n- `decimalOffset` should be `3` (position of `.`) but is passed as `0`\n- This causes `initNumLong()` in `JsonNumberImpl` to misparse the number\n\n## Reproduction\n\n```java\nvar jn = JsonNumber.of(123.0);\njn.toString(); // \"123.0\" - OK\njn.toDouble(); // 123.0 - OK\njn.toLong(); // THROWS: \"123.0 cannot be represented as a long\"\n // EXPECTED: 123L (per API docs, \"123.0\" should be convertible)\n```\n\n## Comparison with Json.parse()\n\n```java\nvar parsed = Json.parse(\"123.0\");\nparsed.toLong(); // 123L - WORKS correctly\n```\n\nThe difference is that `Json.parse()` correctly computes the `decimalOffset` during parsing.\n\n## Suggested Fix\n\nOption 1 - Reuse `JsonNumber.of(String)` which delegates to parser:\n```java\nstatic JsonNumber of(double num) {\n if (!Double.isFinite(num)) {\n throw new IllegalArgumentException(\"Not a valid JSON number\");\n }\n return JsonNumber.of(Double.toString(num));\n}\n```\n\nOption 2 - Compute correct offsets:\n```java\nstatic JsonNumber of(double num) {\n if (!Double.isFinite(num)) {\n throw new IllegalArgumentException(\"Not a valid JSON number\");\n }\n var str = Double.toString(num);\n var chars = str.toCharArray();\n int dec = str.indexOf('.');\n int exp = str.indexOf('e');\n if (exp == -1) exp = str.indexOf('E');\n return new JsonNumberImpl(chars, 0, chars.length, \n dec == -1 ? -1 : dec, \n exp == -1 ? -1 : exp);\n}\n```\n\n## This is an Upstream Bug\n\nThis bug exists in OpenJDK jdk-sandbox `json` branch at commit `91a479d`. The upstream tests in `TestJsonNumber.java` do not cover this case - they test `of(double).toDouble()` but never `of(double).toLong()` for integral doubles.\n\n## Affected Versions\n\n- jdk-sandbox json branch (upstream)\n- java.util.json.Java21 backport 0.1.9 (this repo, synced from upstream)\n","author":{"url":"https://github.com/simbo1905","@type":"Person","name":"simbo1905"},"datePublished":"2026-01-26T00:14:19.000Z","interactionStatistic":{"@type":"InteractionCounter","interactionType":"https://schema.org/CommentAction","userInteractionCount":1},"url":"https://github.com/118/java.util.json.Java21/issues/118"}
| route-pattern | /_view_fragments/issues/show/:user_id/:repository/:id/issue_layout(.:format) |
| route-controller | voltron_issues_fragments |
| route-action | issue_layout |
| fetch-nonce | v2:97fc7675-4863-d867-9cda-b0271089f280 |
| current-catalog-service-hash | 81bb79d38c15960b92d99bca9288a9108c7a47b18f2423d0f6438c5b7bcd2114 |
| request-id | BF9E:3CAE76:79152DD:9CD1EC7:697E601E |
| html-safe-nonce | f792050a59b5cbf92b7d90cda543e7b9792aaca1d58cd6a58f23e5ee4eec8739 |
| visitor-payload | eyJyZWZlcnJlciI6IiIsInJlcXVlc3RfaWQiOiJCRjlFOjNDQUU3Njo3OTE1MkREOjlDRDFFQzc6Njk3RTYwMUUiLCJ2aXNpdG9yX2lkIjoiNjgzNTQzMjEzNzA0NjM0Mzk4IiwicmVnaW9uX2VkZ2UiOiJpYWQiLCJyZWdpb25fcmVuZGVyIjoiaWFkIn0= |
| visitor-hmac | c1b421a22352de7561ac6fd553db763ae5df5b9ccbf20d965cdb82f908ce0ca0 |
| hovercard-subject-tag | issue:3854068458 |
| github-keyboard-shortcuts | repository,issues,copilot |
| google-site-verification | Apib7-x98H0j5cPqHWwSMm6dNU4GmODRoqxLiDzdx9I |
| octolytics-url | https://collector.github.com/github/collect |
| analytics-location | / |
| fb:app_id | 1401488693436528 |
| apple-itunes-app | app-id=1477376905, app-argument=https://github.com/_view_fragments/issues/show/simbo1905/java.util.json.Java21/118/issue_layout |
| twitter:image | https://opengraph.githubassets.com/34d75fda6b18ff4b92eff9fac4424835bae2b336b675195ba90d6d6123242394/simbo1905/java.util.json.Java21/issues/118 |
| twitter:card | summary_large_image |
| og:image | https://opengraph.githubassets.com/34d75fda6b18ff4b92eff9fac4424835bae2b336b675195ba90d6d6123242394/simbo1905/java.util.json.Java21/issues/118 |
| og:image:alt | Summary The JsonNumber.of(double) factory method has a bug where it hardcodes decimalOffset=0 and exponentOffset=0 when creating the JsonNumberImpl. This causes toLong() to fail for integral double... |
| og:image:width | 1200 |
| og:image:height | 600 |
| og:site_name | GitHub |
| og:type | object |
| og:author:username | simbo1905 |
| hostname | github.com |
| expected-hostname | github.com |
| None | 60279d4097367e16897439d16d6bbe4180663db828c666eeed2656988ffe59f6 |
| turbo-cache-control | no-preview |
| go-import | github.com/simbo1905/java.util.json.Java21 git https://github.com/simbo1905/java.util.json.Java21.git |
| octolytics-dimension-user_id | 322608 |
| octolytics-dimension-user_login | simbo1905 |
| octolytics-dimension-repository_id | 1025867939 |
| octolytics-dimension-repository_nwo | simbo1905/java.util.json.Java21 |
| octolytics-dimension-repository_public | true |
| octolytics-dimension-repository_is_fork | false |
| octolytics-dimension-repository_network_root_id | 1025867939 |
| octolytics-dimension-repository_network_root_nwo | simbo1905/java.util.json.Java21 |
| turbo-body-classes | logged-out env-production page-responsive |
| disable-turbo | false |
| browser-stats-url | https://api.github.com/_private/browser/stats |
| browser-errors-url | https://api.github.com/_private/browser/errors |
| release | 7c85641c598ad130c74f7bcc27f58575cac69551 |
| ui-target | canary-1 |
| theme-color | #1e2327 |
| color-scheme | light dark |
Links:
Viewport: width=device-width