fix: multipleOf float precision with tolerance-based check#98
fix: multipleOf float precision with tolerance-based check#98jarvis9443 wants to merge 2 commits intomasterfrom
Conversation
The previous check used math.modf to verify that the quotient of value/multipleOf is an integer. Due to IEEE 754 floating-point precision, this fails for valid cases like 1.13 / 0.01 which yields 112.99999999999999 instead of 113. Replace with a tolerance-based check: round the quotient and verify the difference is within 1e-10.
There was a problem hiding this comment.
Pull request overview
Updates the Lua JSON Schema validator’s multipleOf handling to be resilient to IEEE-754 floating-point rounding artifacts, and adds extra spec coverage for float multipleOf scenarios.
Changes:
- Switch float
multipleOfvalidation from an integer-quotient check to a tolerance-based approach. - Add new extra spec cases for float and integer
multipleOf. - Include the new extra spec file in draft4 and draft7 test runners.
Reviewed changes
Copilot reviewed 4 out of 4 changed files in this pull request and generated 2 comments.
| File | Description |
|---|---|
lib/jsonschema.lua |
Reworks float multipleOf validation to use rounding + tolerance instead of math.modf integer-quotient detection. |
spec/extra/multipleOf.json |
Adds extra test cases covering float precision edge cases and basic integer multiples. |
t/draft4.lua |
Adds the new extra spec file to the supported test list for draft4 runs. |
t/draft7.lua |
Adds the new extra spec file to the supported test list for draft7 runs. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (2)
🚧 Files skipped from review as they are similar to previous changes (2)
📝 WalkthroughWalkthroughReplaced exact integer-check for Changes
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes 🚥 Pre-merge checks | ✅ 6✅ Passed checks (6 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Comment |
There was a problem hiding this comment.
🧹 Nitpick comments (1)
spec/extra/multipleOf.json (1)
8-34: Add edge-case tests at the tolerance boundary.Current cases are good, but they don’t lock behavior right around
1e-10. Please add one case just within tolerance (valid) and one just outside (invalid) to prevent regressions in the comparison threshold.🧪 Suggested test additions
"tests": [ @@ { "description": "100.05 is a multiple of 0.01", "data": 100.05, "valid": true }, + { + "description": "within tolerance is treated as multiple", + "data": 1.1300000000005, + "valid": true + }, + { + "description": "outside tolerance is not treated as multiple", + "data": 1.130000000002, + "valid": false + }, { "description": "1.1312 is not a multiple of 0.01", "data": 1.1312, "valid": false },🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@spec/extra/multipleOf.json` around lines 8 - 34, Add two edge-case entries to the "tests" array to exercise the 1e-10 tolerance boundary: one test object with "description" like "1.13000000009 is within 1e-10 tolerance of multiple of 0.01", "data": 1.13000000009, "valid": true, and another with "description" like "1.13000000011 is outside 1e-10 tolerance of multiple of 0.01", "data": 1.13000000011, "valid": false; place them alongside the existing test objects so the "tests" array now contains both the just-within and just-outside boundary checks.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Nitpick comments:
In `@spec/extra/multipleOf.json`:
- Around line 8-34: Add two edge-case entries to the "tests" array to exercise
the 1e-10 tolerance boundary: one test object with "description" like
"1.13000000009 is within 1e-10 tolerance of multiple of 0.01", "data":
1.13000000009, "valid": true, and another with "description" like "1.13000000011
is outside 1e-10 tolerance of multiple of 0.01", "data": 1.13000000011, "valid":
false; place them alongside the existing test objects so the "tests" array now
contains both the just-within and just-outside boundary checks.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: a00513be-05e3-421f-b531-35de60b9ec61
📒 Files selected for processing (4)
lib/jsonschema.luaspec/extra/multipleOf.jsont/draft4.luat/draft7.lua
Use 1e-12 relative tolerance scaled by the rounded quotient magnitude, preventing false positives with large multipleOf values (e.g. multipleOf=1e9). Add test case for large multipleOf values as suggested.
The previous check used
math.modfto verify that the quotient ofvalue / multipleOfis an integer. Due to IEEE 754 floating-point precision, this fails for valid cases like1.13 / 0.01which yields112.99999999999999instead of113.Replaced with a tolerance-based check: round the quotient and verify the difference is within
1e-10.Added test cases in
spec/extra/multipleOf.jsoncovering both valid and invalid float multipleOf scenarios.Summary by CodeRabbit
Bug Fixes
Tests