From 5c60049cf4120def22f2daba8b45260f8fab5d03 Mon Sep 17 00:00:00 2001 From: Sam Date: Sat, 31 Jan 2026 04:27:34 +0530 Subject: [PATCH 1/4] updated the lcm logic with decimal-aware and test case is added --- src/error-handlers/multipleOf.js | 27 ++++++++++--- src/test-suite/tests/multipleOf.json | 60 +++++++++++++++++++++++----- 2 files changed, 72 insertions(+), 15 deletions(-) diff --git a/src/error-handlers/multipleOf.js b/src/error-handlers/multipleOf.js index 5589929..04980d0 100644 --- a/src/error-handlers/multipleOf.js +++ b/src/error-handlers/multipleOf.js @@ -39,18 +39,29 @@ const multipleOfErrorHandler = async (normalizedErrors, instance, localization) return errors; }; +/** + * @param {number} value + * @returns {number} + */ +const countDecimals = (value) => value.toString().split(".")[1]?.length || 0; + /** * @param {number} a * @param {number} b * @returns {number} */ const gcd = (a, b) => { - while (b !== 0) { - const temp = b; - b = a % b; - a = temp; + const m = 10 ** Math.max(countDecimals(a), countDecimals(b)); + let x = Math.round(a * m); + let y = Math.round(b * m); + + while (y !== 0) { + const temp = y; + y = x % y; + x = temp; } - return Math.abs(a); + + return Math.abs(x) / m; }; /** @@ -59,7 +70,11 @@ const gcd = (a, b) => { * @returns {number} */ const lcm = (a, b) => { - return Math.abs(a * b) / gcd(a, b); + const m = 10 ** Math.max(countDecimals(a), countDecimals(b)); + const x = Math.round(a * m); + const y = Math.round(b * m); + + return Math.abs(x * y) / (gcd(x, y) * m); }; export default multipleOfErrorHandler; diff --git a/src/test-suite/tests/multipleOf.json b/src/test-suite/tests/multipleOf.json index 766f089..9b5c05c 100644 --- a/src/test-suite/tests/multipleOf.json +++ b/src/test-suite/tests/multipleOf.json @@ -1,6 +1,5 @@ { "$schema": "../test-suite.schema.json", - "description": "The multipleOf keyword", "tests": [ { @@ -12,9 +11,13 @@ "errors": [ { "messageId": "multipleOf-message", - "messageParams": { "multipleOf": "3" }, + "messageParams": { + "multipleOf": "3" + }, "instanceLocation": "#", - "schemaLocations": ["#/multipleOf"] + "schemaLocations": [ + "#/multipleOf" + ] } ] }, @@ -30,20 +33,59 @@ "description": "multiple multipleOf constraints (LCM of 4, 6, and 8)", "schema": { "allOf": [ - { "multipleOf": 4 }, - { "multipleOf": 6 }, - { "multipleOf": 8 } + { + "multipleOf": 4 + }, + { + "multipleOf": 6 + }, + { + "multipleOf": 8 + } ] }, "instance": 10, "errors": [ { "messageId": "multipleOf-message", - "messageParams": { "multipleOf": "24" }, + "messageParams": { + "multipleOf": "24" + }, "instanceLocation": "#", - "schemaLocations": ["#/allOf/0/multipleOf", "#/allOf/1/multipleOf", "#/allOf/2/multipleOf"] + "schemaLocations": [ + "#/allOf/0/multipleOf", + "#/allOf/1/multipleOf", + "#/allOf/2/multipleOf" + ] + } + ] + }, + { + "description": "multiple decimal multipleOf constraints (LCM 0.2 and 0.3)", + "schema": { + "allOf": [ + { + "multipleOf": 0.2 + }, + { + "multipleOf": 0.3 + } + ] + }, + "instance": 0.7, + "errors": [ + { + "messageId": "multipleOf-message", + "messageParams": { + "multipleOf": "0.6" + }, + "instanceLocation": "#", + "schemaLocations": [ + "#/allOf/0/multipleOf", + "#/allOf/1/multipleOf" + ] } ] } ] -} +} \ No newline at end of file From c7caba980732bc3d90202817efc9be7278bc50c4 Mon Sep 17 00:00:00 2001 From: Sam Date: Sat, 31 Jan 2026 04:44:35 +0530 Subject: [PATCH 2/4] test is fixed --- src/test-suite/tests/multipleOf.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test-suite/tests/multipleOf.json b/src/test-suite/tests/multipleOf.json index 9b5c05c..b1a6c4e 100644 --- a/src/test-suite/tests/multipleOf.json +++ b/src/test-suite/tests/multipleOf.json @@ -61,7 +61,7 @@ ] }, { - "description": "multiple decimal multipleOf constraints (LCM 0.2 and 0.3)", + "description": "multiple decimal multipleOf constraints (LCM of 0.2 and 0.3)", "schema": { "allOf": [ { From 2ce1cb0dc24516d4f66170c3b09115c4c911b14b Mon Sep 17 00:00:00 2001 From: Sam Date: Mon, 2 Feb 2026 09:37:13 +0530 Subject: [PATCH 3/4] fix: whitespace cleanup From 92f6efa086425558c27e83f48190fd3e35076102 Mon Sep 17 00:00:00 2001 From: Sam Date: Mon, 2 Feb 2026 09:56:50 +0530 Subject: [PATCH 4/4] fix: revert formatting changes --- src/test-suite/tests/multipleOf.json | 50 ++++++++-------------------- 1 file changed, 13 insertions(+), 37 deletions(-) diff --git a/src/test-suite/tests/multipleOf.json b/src/test-suite/tests/multipleOf.json index b1a6c4e..067638d 100644 --- a/src/test-suite/tests/multipleOf.json +++ b/src/test-suite/tests/multipleOf.json @@ -1,5 +1,6 @@ { "$schema": "../test-suite.schema.json", + "description": "The multipleOf keyword", "tests": [ { @@ -11,13 +12,9 @@ "errors": [ { "messageId": "multipleOf-message", - "messageParams": { - "multipleOf": "3" - }, + "messageParams": { "multipleOf": "3" }, "instanceLocation": "#", - "schemaLocations": [ - "#/multipleOf" - ] + "schemaLocations": ["#/multipleOf"] } ] }, @@ -33,30 +30,18 @@ "description": "multiple multipleOf constraints (LCM of 4, 6, and 8)", "schema": { "allOf": [ - { - "multipleOf": 4 - }, - { - "multipleOf": 6 - }, - { - "multipleOf": 8 - } + { "multipleOf": 4 }, + { "multipleOf": 6 }, + { "multipleOf": 8 } ] }, "instance": 10, "errors": [ { "messageId": "multipleOf-message", - "messageParams": { - "multipleOf": "24" - }, + "messageParams": { "multipleOf": "24" }, "instanceLocation": "#", - "schemaLocations": [ - "#/allOf/0/multipleOf", - "#/allOf/1/multipleOf", - "#/allOf/2/multipleOf" - ] + "schemaLocations": ["#/allOf/0/multipleOf", "#/allOf/1/multipleOf", "#/allOf/2/multipleOf"] } ] }, @@ -64,28 +49,19 @@ "description": "multiple decimal multipleOf constraints (LCM of 0.2 and 0.3)", "schema": { "allOf": [ - { - "multipleOf": 0.2 - }, - { - "multipleOf": 0.3 - } + { "multipleOf": 0.2 }, + { "multipleOf": 0.3 } ] }, "instance": 0.7, "errors": [ { "messageId": "multipleOf-message", - "messageParams": { - "multipleOf": "0.6" - }, + "messageParams": { "multipleOf": "0.6" }, "instanceLocation": "#", - "schemaLocations": [ - "#/allOf/0/multipleOf", - "#/allOf/1/multipleOf" - ] + "schemaLocations": ["#/allOf/0/multipleOf", "#/allOf/1/multipleOf"] } ] } ] -} \ No newline at end of file +}