commons-lang icon indicating copy to clipboard operation
commons-lang copied to clipboard

LANG-1519 Add zero, positive & negative util methods

Open nnivruth opened this issue 5 years ago • 13 comments

Create Integer Utils class for useful integer operations and a placeholder for adding more useful/important utility functions

nnivruth avatar Feb 21 '20 02:02 nnivruth

https://issues.apache.org/jira/browse/LANG-1519

nnivruth avatar Feb 21 '20 02:02 nnivruth

Coverage Status

Coverage increased (+0.02%) to 95.109% when pulling 1f498beda2a0384c255e134d548163dcdf7a0061 on nnivruth:master into 1c42dfb05791a1172e03d355d296327c013177f9 on apache:master.

coveralls avatar Feb 21 '20 03:02 coveralls

Shouldn't this be the part of Math-related projects? like common numbers?

ameyjadiye avatar Feb 21 '20 09:02 ameyjadiye

-1 in Commons Lang, we had a NumberUtils class in 2.x but it was deprecated and removed in 3.0. That code now lives in Apache Commons Math IIRC. Also, it does not make sense as typed to Integer when you can type to its Number superclass.

garydgregory avatar Feb 21 '20 13:02 garydgregory

@ameyjadiye @garydgregory refactored & moved to NumberUtils

nnivruth avatar Feb 22 '20 23:02 nnivruth

What should these method return when a double is not-a-number?

garydgregory avatar Feb 25 '20 21:02 garydgregory

What should these method return when a double is not-a-number?

@garydgregory, great question. IMO the methods isZero(), isPositive(), isNegative() should return false for float/double NaNs & vice versa for isNotZero(), isNotPositive(), isNotNegative(). I've added these to the test cases as well.

nnivruth avatar Feb 26 '20 01:02 nnivruth

What about other JRE numbers like atomic numbers and big numbers? How should those be treated?

garydgregory avatar Mar 02 '20 19:03 garydgregory

What about other JRE numbers like atomic numbers and big numbers? How should those be treated?

@garydgregory one way to handle special numbers (BigInteger, BigDecimal, AtomicInteger, AtomicLong) is to add them as special instance checks (additional else-if blocks in each method) but not sure if that's the best way. do you have any suggestions/feedback?

nnivruth avatar Mar 19 '20 04:03 nnivruth

Hi @nnivruth In general, since we are a general purpose library, I would say that you should consider all subclasses of Number that are built-in the Java 8 JRE with maybe a bias to considering only what is in Java 11's java.base module in order to make it easier on us going forward though I would imagine that our requiring Java 11 as a base requirement is a long ways off (just a guess on that one.)

garydgregory avatar Mar 19 '20 12:03 garydgregory

Hi @nnivruth In general, since we are a general purpose library, I would say that you should consider all subclasses of Number that are built-in the Java 8 JRE with maybe a bias to considering only what is in Java 11's java.base module in order to make it easier on us going forward though I would imagine that our requiring Java 11 as a base requirement is a long ways off (just a guess on that one.)

Thanks @garydgregory ! I've also added Long Accumulator, Long Adder, Double Accumulator, Double Adder which covers known Number subclasses.

nnivruth avatar Mar 19 '20 18:03 nnivruth

@nnivruth , Thank you for your updates. The code covers all the cases it seems which is nice. The drawback ATM is that it does not feel very OO. I am wondering if all of this could be implemented in terms of a new utility method called compare(Number, Number) which would allow the isZero, isPositive and isNegative to be implemented by calling compare(aNumber, ZERO). More thinking and experimenting needed...

This is all non-trivial, so I think I might cut a 3.10 RC which I am late on and this PR would end up in 3.11.

garydgregory avatar Mar 22 '20 17:03 garydgregory

@garydgregory , Been thinking and trying to make these functions more OO and rely on a single method but seeing some difficulties with type casting (esp for special types of number implementations - BigDecimal, etc), NaNs and custom Number implementations.

Some examples:

  • the isZero() function with the current impl does a direct equality check and returns true when passed with (-0.0d). IMO this is acceptable and correct but with the new impl it'll return false

  • the functions isZero(), isPositive(), isNegative() return false for float/double NaNs & vice versa for isNotZero(), isNotPositive(), isNotNegative() but with compare we might have to add special checks for these scenarios

your thoughts/inputs on how to proceed?

nnivruth avatar Apr 17 '20 03:04 nnivruth