Skip to content

Add test for multipleOf to see if a library has problem with floating point rounding errors #68

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

Closed
defel opened this issue Nov 27, 2014 · 4 comments

Comments

@defel
Copy link

defel commented Nov 27, 2014

Hi,

please see: zaggino/z-schema#69

Using multipleOf can lead to wrong validation errors in some libraries which are written in

For example the following schema:

{ 
    "type": "object",
    "properties": {
      "decimal": {
        "type": "number",
        "multipleOf": 0.01
      }   
    }   
}

Validates correctly against the following documents:

{"decimal": 100}
{"decimal": 100.10}

But not against:

{"decimal": 136.67}

This is because rounding errors of floats in javascript (see http://floating-point-gui.de/):

100 / 0.01
=> 10000

100.01 / 0.01
=> 10001

// but:
136.67 / 0.01
=> 13666.999999999998

Please add a test to validate agains this error case.

@Julian
Copy link
Member

Julian commented Nov 27, 2014

python-jsonschema/jsonschema#185 and python-jsonschema/jsonschema#188 are related here.

I'm unconvinced that this belongs here, and if it does, it almost certainly belongs in optional/. This behavior depends on the behavior of the JSON deserialization libraries in all the relevant languages. AFAIK, the general behavior of all of them is to parse numbers into floats by default. Some (as I mentioned there) allow you to get exact precision if you ask for it. This is mentioned in the JSON RFC (7159):

This specification allows implementations to set limits on the range
and precision of numbers accepted. Since software that implements
IEEE 754-2008 binary64 (double precision) numbers [IEEE754] is
generally available and widely used, good interoperability can be
achieved by implementations that expect no more precision or range
than these provide, in the sense that implementations will
approximate JSON numbers within the expected precision. A JSON
number such as 1E400 or 3.141592653589793238462643383279 may indicate
potential interoperability problems, since it suggests that the
software that created it expects receiving software to have greater
capabilities for numeric magnitude and precision than is widely
available.

So, if someone would like this test, I'd merge it, but only as an optional test, it's not mandatory, expected, or even reasonably-reliant behavior unless you control both ends as I understand the specifications (of jsonschema and of JSON).

@Julian
Copy link
Member

Julian commented Nov 27, 2014

I see @fge just made the same comment on the PR (#69).

@defel
Copy link
Author

defel commented Nov 27, 2014

ok, I understand the problem and why the validation is correct, and using multipleOf is just wrong in my case.

13667*0.01 is 136.67000000000002 and not 136.67 as I thought naive.

After reading https://stackoverflow.com/questions/3730019/why-not-use-double-or-float-to-represent-currency - I will use type string and regexp to validate for correct price representation in my schema.

Thank you for your explanation.

@defel defel closed this as completed Nov 27, 2014
@geraintluff
Copy link
Contributor

I agree with @Julian - test seems good, but should be in optional/.

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

No branches or pull requests

3 participants