26
BigInteger bigInteger = ...;


if(bigInteger.longValue() > 0) {  //original code
    //bigger than 0
}

//should I change to this?
if(bigInteger.compareTo(BigInteger.valueOf(0)) == 1) {
    //bigger than 0
}

I need to compare some arbitary BigInteger values. I wonder which approach is correct. Given the above code which one should be used? The original code is on the top.. I am thinking to change it to the second approach.

Rosdi Kasim
  • 24,267
  • 23
  • 130
  • 154

3 Answers3

41

The first approach is wrong if you want to test if the BigInteger has a postive value: longValue just returns the low-order 64 bit which may revert the sign... So the test could fail for a positive BigInteger.

The second approach is better (see Bozhos answer for an optimization).

Another alternative: BigInteger#signum returns 1 if the value is positive:

if (bigInteger.signum() == 1) {
 // bigger than 0
}
Community
  • 1
  • 1
Andreas Dolk
  • 113,398
  • 19
  • 180
  • 268
31

If you are using BigInteger, this assumes you need bigger numbers than long can handle. So don't use longValue(). Use compareTo. With your example it better be:

if (bigInteger.compareTo(BigInteger.ZERO) > 0) {

}
Bozho
  • 588,226
  • 146
  • 1,060
  • 1,140
18

This is not a direct answer, but an important note about using compareTo().

When checking the value of compareTo(), always test for x < 0, x > 0 and x == 0.
Do not test for x == 1

From the Comparable.compareTo() javadocs:

Compares this object with the specified object for order. Returns a negative integer, zero, or a positive integer as this object is less than, equal to, or greater than the specified object.

Note:

  • A negative integer, not -1.
  • A positive integer, not 1.

True, checking for ==1 and ==-1 would work for BigInteger. This is the BigInteger.compareTo() code:

public int compareTo(BigInteger val) {
    if (signum == val.signum) {
        switch (signum) {
        case 1:
            return compareMagnitude(val);
        case -1:
            return val.compareMagnitude(this);
        default:
            return 0;
        }
    }
    return signum > val.signum ? 1 : -1;
}

But it's still bad practice, and explicitly recommended against in the JavaDocs:

Compares this BigInteger with the specified BigInteger. This method is provided in preference to individual methods for each of the six boolean comparison operators (<, ==, >, >=, !=, <=). The suggested idiom for performing these comparisons is: (x.compareTo(y) <op> 0), where <op> is one of the six comparison operators.

Sean Patrick Floyd
  • 292,901
  • 67
  • 465
  • 588
  • The spec for `BigInteger.compareTo()` does explicitly say `-1, 0, and 1` but I do agree using `x < 0`, `x == 0`, `x > 0` feels more intuitive rather than `x == -1`, `x == 0`, `x == 1`. – Rosdi Kasim Nov 04 '10 at 14:53
  • 1
    @Rosdi but it also says *The suggested idiom for performing these comparisons is: (`x.compareTo(y) 0`), where `` is one of the six comparison operators.* – Sean Patrick Floyd Nov 04 '10 at 14:56