-
-
Notifications
You must be signed in to change notification settings - Fork 94
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
fix: Fix multipleOf to work with decimals #436
base: master
Are you sure you want to change the base?
Conversation
A more simplistic approach to validating floats, where we multiply both value and multipleOf with 10 until multipleOf does not have any fractions, and then compare them as integers. This should work since both numbers are fetched from a text string that can't be repeating.
Pinging @Stranger6667. Is there any way we can bring this issue forward? I'm affected as well by the bug #397. Let me know if I can help. |
I can confirm the fix works. |
I've to correct myself. The solution doesn't always work. For example, the fix fails to validate that If found this issue by fuzzing with diff --git a/jsonschema/src/keywords/multiple_of.rs b/jsonschema/src/keywords/multiple_of.rs
index 64c1509..3cba1df 100644
--- a/jsonschema/src/keywords/multiple_of.rs
+++ b/jsonschema/src/keywords/multiple_of.rs
@@ -100,6 +100,8 @@ mod tests {
#[test_case(&json!({"multipleOf": 0.1}), &json!(1.2))]
#[test_case(&json!({"multipleOf": 0.1}), &json!(1.3))]
#[test_case(&json!({"multipleOf": 0.02}), &json!(1.02))]
+ #[test_case(&json!({"multipleOf": 0.1}), &json!(78.0))]
fn multiple_of_is_valid(schema: &Value, instance: &Value) {
tests_util::is_valid(schema, instance)
} |
The core of this PR is this code: while tmp_item.fract() != 0. {
tmp_item *= 10.0;
tmp_multiple_of *= 10.0;
}
tmp_item % tmp_multiple_of == 0.0 It returns Since |
I found a fix. But I'm not sure yet if the fix works for all inputs. diff --git a/jsonschema/src/keywords/multiple_of.rs b/jsonschema/src/keywords/multiple_of.rs
index 64c1509..eb49b59 100644
--- a/jsonschema/src/keywords/multiple_of.rs
+++ b/jsonschema/src/keywords/multiple_of.rs
@@ -35,7 +35,9 @@ impl Validate for MultipleOfValidator {
tmp_multiple_of *= 10.0;
}
- tmp_item % tmp_multiple_of == 0.0
+ (tmp_item / tmp_multiple_of).fract() == 0.0
+
+
} else {
true
} |
My solution doesn't work for very large numbers and a value for "mutlipleOf" that's below 1. diff --git a/jsonschema/src/keywords/multiple_of.rs b/jsonschema/src/keywords/multiple_of.rs
index 64c1509..3d431a8 100644
--- a/jsonschema/src/keywords/multiple_of.rs
+++ b/jsonschema/src/keywords/multiple_of.rs
@@ -100,6 +100,8 @@ mod tests {
#[test_case(&json!({"multipleOf": 0.1}), &json!(1.2))]
#[test_case(&json!({"multipleOf": 0.1}), &json!(1.3))]
#[test_case(&json!({"multipleOf": 0.02}), &json!(1.02))]
+ #[test_case(&json!({"multipleOf": 0.5}), &json!(1e308))]
fn multiple_of_is_valid(schema: &Value, instance: &Value) {
tests_util::is_valid(schema, instance)
} |
Here's a relevant discussion explaining why |
c8ee78a
to
8eacf2d
Compare
A more simplistic approach to validating floats, where we multiply both value and multipleOf with 10 until multipleOf does not have any fractions, and then compare them as integers. This should work since both numbers are fetched from a text string that can't be repeating. Could possibly help solve #397