Skip to content

fix: multipleOf float precision with tolerance-based check#98

Open
jarvis9443 wants to merge 2 commits intomasterfrom
fix/multipleof-float-precision
Open

fix: multipleOf float precision with tolerance-based check#98
jarvis9443 wants to merge 2 commits intomasterfrom
fix/multipleof-float-precision

Conversation

@jarvis9443
Copy link
Copy Markdown
Contributor

@jarvis9443 jarvis9443 commented Apr 22, 2026

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.

Replaced with a tolerance-based check: round the quotient and verify the difference is within 1e-10.

Added test cases in spec/extra/multipleOf.json covering both valid and invalid float multipleOf scenarios.

Summary by CodeRabbit

  • Bug Fixes

    • Improved multipleOf validation for floating‑point numbers with enhanced tolerance handling to reduce false negatives on precision-sensitive values.
  • Tests

    • Added comprehensive multipleOf test suites covering small decimals, large divisors, and integer cases; test harnesses for draft4 and draft7 now include these scenarios to ensure correct behavior.

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.
Copilot AI review requested due to automatic review settings April 22, 2026 10:34
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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 multipleOf validation 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.

Comment thread lib/jsonschema.lua Outdated
Comment thread spec/extra/multipleOf.json
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Apr 22, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: bf13843b-adf9-45dc-a772-e0f13ecb908c

📥 Commits

Reviewing files that changed from the base of the PR and between 071222c and 0c41dff.

📒 Files selected for processing (2)
  • lib/jsonschema.lua
  • spec/extra/multipleOf.json
🚧 Files skipped from review as they are similar to previous changes (2)
  • lib/jsonschema.lua
  • spec/extra/multipleOf.json

📝 Walkthrough

Walkthrough

Replaced exact integer-check for multipleOf on non-integers with a rounding-and-tolerance comparison to avoid floating-point precision failures. Added spec/extra/multipleOf.json with multiple test suites and registered it in t/draft4.lua and t/draft7.lua.

Changes

Cohort / File(s) Summary
Validator logic
lib/jsonschema.lua
Reworked multipleOf handling for non-integer numbers: compute quotient = value / mof, rounded = math.floor(quotient + 0.5), set tol = 1e-12 * abs(rounded) (with nonzero fallback when rounded == 0), and fail only if abs(quotient - rounded) > tol. Failure message and surrounding flow unchanged.
Test specifications
spec/extra/multipleOf.json
Added new JSON containing multiple test suites for type: "number" / multipleOf: suites cover small fractional divisor (0.01), integer divisor (3), and a large fractional divisor (1000000000.5) with explicit valid/invalid cases.
Test runner configs
t/draft4.lua, t/draft7.lua
Appended spec/extra/multipleOf.json to the supported lists so the new test suites are included in draft4 and draft7 benchmark runs.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

🚥 Pre-merge checks | ✅ 6
✅ Passed checks (6 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately describes the main change: fixing the multipleOf validation for floating-point numbers by implementing a tolerance-based check instead of the previous math.modf approach.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
E2e Test Quality Review ✅ Passed PR provides comprehensive E2E test coverage with tests exercising the complete validation pipeline, covering IEEE 754 float precision issues, integer multiples, and large values with clear descriptions and straightforward assertions.
Security Check ✅ Passed PR modifies JSON Schema multipleOf validation to fix floating-point precision. No authentication, credential handling, database operations, TLS config, or authorization logic present.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/multipleof-float-precision

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 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

📥 Commits

Reviewing files that changed from the base of the PR and between 7268433 and 071222c.

📒 Files selected for processing (4)
  • lib/jsonschema.lua
  • spec/extra/multipleOf.json
  • t/draft4.lua
  • t/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.
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.

2 participants