Skip to content
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

ValidationUtils.isNonnegativeInteger returns true for -0 #47

Open
thedavidmeister opened this issue Sep 10, 2017 · 3 comments
Open

ValidationUtils.isNonnegativeInteger returns true for -0 #47

thedavidmeister opened this issue Sep 10, 2017 · 3 comments

Comments

@thedavidmeister
Copy link
Contributor

thedavidmeister commented Sep 10, 2017

Just something I came across while working on #46 - i'm not sure if this is desired behaviour or not

@tonyofbyteball
Copy link
Member

I didn't know about signed 0 until today. Where can we meet it?

@thedavidmeister
Copy link
Contributor Author

thedavidmeister commented Sep 23, 2017

@tonyofbyteball https://stackoverflow.com/questions/7223359/are-0-and-0-the-same

It's part of IEEE 754. Most of the time you can ignore it because there is no difference in strict equality checks or addition/subtraction, etc. -0 === 0 and 1+ -0 === 1 + 0 etc.

The main difference in practical terms is when dividing or multiplying by zero as:

1/-0 === -Infinity and 1/0 === Infinity

1 * -0; // -0 and 1 * 0; // 0

Of course, dividing anything by zero is problematic for other reasons anyway...

JS also returns false for Object.is(-0,0).

The reason it is coming up at all is because JS doesn't actually have an explicit integer number type, as it uses doubles for everything. Even after ES6 introduced Number.isInteger it still uses doubles for all "integers" - this breaks down a bit at 0 and outside Number.MIN_SAFE_INTEGER and Number.MAX_SAFE_INTEGER.

As a comparison, here is the output from my REPL in clojure (using the JVM which has both floats and integer number types):

boot.user=> (/ 1 0)
java.lang.ArithmeticException: Divide by zero
boot.user=> (/ 1 -0)
java.lang.ArithmeticException: Divide by zero
boot.user=> (/ 1 0.0)
Infinity
boot.user=> (/ 1 -0.0)
-Infinity

You can see there is a difference between signed 0 in doubles but dividing by integer 0 is always an exception as there isn't an integer negative zero AFAIK.

IMO the JVM behaviour of integers is usually what you want, dividing by the integer 0 is undefined in normal arithmetic and throwing an error is more helpful than returning +/-Infinity to be propagated through the rest of your code :/

@thedavidmeister
Copy link
Contributor Author

thedavidmeister commented Sep 23, 2017

So yeah... tbh it could go either way...

Argument for:

There is no difference between the integer represented by both -0 and 0 as there is only one integer 0 so therefore -0 is a negative double but not a negative integer, so therefore isNonnegativeInteger should return true.

Argument against:

JavaScript does not have any integers in reality, so following IEEE 754 there is a difference between -0 and 0 that will be apparent as soon as you multiply or divide anything by either of them. Even though we are willing to take ES6's lead on designating a subset of doubles as "integers" as per Number.isInteger, and -0 is definitely one of these integers, it is also a negative value, so we cannot say that it is "non negative". Therefore isNonnegativeInteger should return false.

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

2 participants