Skip to content

multipleOf - IEEE-754 floating point rounding error #193

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

Conversation

spacebaboon
Copy link

Add tests for multipleOf 0.1, to cover IEEE-754 floating point rounding error.
0.1 cannot be exactly represented in binary.
http://docs.oracle.com/cd/E19957-01/806-3568/ncg_goldberg.html
This can cause JSON Schema implementations to assert that, e.g. 2.4 is not a multiple of 0.1.

For example, in a browser console, try evaluating 2.4 / 0.1 compared to 2.5 / 0.1

Testing for multiples of 0.1 is a reasonable enough requirement, IMHO, for example validating user-entered percentages with this precision.

This PR breaks your tests too - sorry! You use Ajv, which has not fixed this issue.

@Julian
Copy link
Member

Julian commented Aug 17, 2017

If this were to be merged, it'd have to go in optional. 2.4 the float is in fact not a multiple of 0.1 the float, for exactly the reason you point out

@spacebaboon
Copy link
Author

Thanks for the quick response 😄

Well, perhaps not strictly in terms of the limitations of IEEE-754 floating point implementations on binary machines, but in terms of having a library to validate multiples of and divisibles by in JSON data, I can't imagine any users not wanting 2.4 to be a multiple of 0.1.

So while I suspect this would break many implementations using your test suite (including the vicious circle here of getting it fixed in Ajv so your tests pass), I also think that would be good, as the maintainers would be encouraged to write a fix to what is essentially a bug (which takes a little more code but is hardly rocket surgery).

@epoberezkin
Copy link
Member

epoberezkin commented Aug 17, 2017

@spacebaboon @Julian I can easily make Ajv pass the test by using the option multipleOfPrecision - that was created exactly for this reason.

I have serious doubts though this should be a part of the test suite, given that it is supposed to be cross platform, and asking all validators to pass this test is a bit too much I think. I was even thinking whether we should limit possible values for multipleOf keyword to integers in the spec...

@Julian
Copy link
Member

Julian commented Aug 17, 2017

Same here, my validator supports using decimals instead of floats if you want this behavior.

@spacebaboon I think there's discussions about this topic on the spec repo for future drafts, but yeah, I don't really think I agree that this is a bug, the behavior is correct for the existing drafts. JSON (and transitively JSON Schema) allow implementations to use IEEE floats when deserializing JSON. Once you've done that, and had functionality like multipleOf in JSON Schema, you have to just live in the world you're in, and provide for functionality that allows for decimals if users want them (heck making it the default is fine with me too, but yeah, as-is, this is at best an optional test I think).

@spacebaboon
Copy link
Author

fair enough, thanks. I hadn't realised deserialising JSON into floats was correct behaviour - or indeed how problematic IEEE floats were.

@Julian
Copy link
Member

Julian commented Aug 17, 2017

json-schema-org/json-schema-spec#312 I think is the most recent discussion, which I think needs a bit of follow-up, but IIRC the conclusion there is, if anything, that the specs might need some more specificity / clarification on positioning / state, moreso than anything changing.

But yeah, it's the JSON spec where lots of this starts really, unfortunately.

Closing for now, but happy to discuss further on whatever issue, thanks for raising certainly!

@Julian Julian closed this Aug 17, 2017
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.

3 participants