Java, comparing BigInteger values - java

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.

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
}

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) {
}

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.

Related

How does compareTo() in Java work with Lists? [duplicate]

What is the difference between returning 0, returning 1 and returning -1 in compareTo() in Java?
Official Definition
From the reference docs of Comparable.compareTo(T):
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.
The implementor must ensure
sgn(x.compareTo(y)) ==
-sgn(y.compareTo(x)) for all x and y. (This implies that x.compareTo(y) must
throw an exception iff y.compareTo(x)
throws an exception.)
The implementor must also ensure that
the relation is transitive:
(x.compareTo(y)>0 && y.compareTo(z)>0)
implies x.compareTo(z)>0.
Finally, the implementor must ensure
that x.compareTo(y)==0 implies that
sgn(x.compareTo(z)) ==
sgn(y.compareTo(z)), for all z.
It is strongly recommended, but not
strictly required that
(x.compareTo(y)==0) == (x.equals(y)).
Generally speaking, any class that
implements the Comparable interface
and violates this condition should
clearly indicate this fact. The
recommended language is "Note: this
class has a natural ordering that is
inconsistent with equals."
In the foregoing description, the
notation sgn(expression) designates
the mathematical signum function,
which is defined to return one of -1,
0, or 1 according to whether the value
of expression is negative, zero or
positive.
My Version
In short:
this.compareTo(that)
returns
a negative int if this < that
0 if this == that
a positive int if this > that
where the implementation of this method determines the actual semantics of < > and == (I don't mean == in the sense of java's object identity operator)
Examples
"abc".compareTo("def")
will yield something smaller than 0 as abc is alphabetically before def.
Integer.valueOf(2).compareTo(Integer.valueOf(1))
will yield something larger than 0 because 2 is larger than 1.
Some additional points
Note: It is good practice for a class that implements Comparable to declare the semantics of it's compareTo() method in the javadocs.
Note: you should read at least one of the following:
the Object Ordering section of
the Collection Trail in the Sun Java
Tutorial
Effective Java by
Joshua Bloch, especially item 12:
Consider implementing Comparable
Java Generics and Collections by
Maurice Naftalin, Philip Wadler, chapter 3.1: Comparable
Warning: you should never rely on the return values of compareTo being -1, 0 and 1. You should always test for x < 0, x == 0, x > 0, respectively.
I use this mnemonic :
a.compareTo(b) < 0 // a < b
a.compareTo(b) > 0 // a > b
a.compareTo(b) == 0 // a == b
You keep the signs and always compare the result of compareTo() to 0
Answer in short: (search your situation)
1.compareTo(0) (return: 1)
1.compareTo(1) (return: 0)
0.comapreTo(1) (return: -1)
take example if we want to compare "a" and "b", i.e ("a" == this)
negative int if a < b
if a == b
Positive int if a > b
It can be used for sorting, and 0 means "equal" while -1, and 1 means "less" and "more (greater)".
Any return value that is less than 0 means that left operand is lesser, and if value is bigger than 0 then left operand is bigger.
int x = thisObject.compareTo(anotherObject);
The compareTo() method returns an int with the following characteristics:
negative If thisObject < anotherObject
zero If thisObject == anotherObject
positive If thisObject > anotherObject
System.out.println(A.compareTo(B)>0?"Yes":"No")
if the value of A>B it will return "Yes" or "No".

Compare Two Strings with Greater than or Lower than Android Studio

i want to compare Two Strings
X = Users Input
Y = System Input
if X is Greater than Y
than show greater than
if X is lower than Y
than show Lower than
Here is my code but it is not working
if (X.compareTo(Y)>-1)
{
Toast.makeText(Activity2.this, "Greater Than", Toast.LENGTH_SHORT).show();
}
else {
Toast.makeText(Activity2.this, "Lower Than", Toast.LENGTH_SHORT).show();
}
I suppose your > -1 is a clever way of testing for "is equal to or greater than". I suggest avoiding such clever code. Writing stupid-simple code (KISS) makes reading and, more to the point here, debugging much easier.
The compareTo method of Comparable interface returns exactly zero if equal. If not equal, the method returns some number greater than zero, or some number less than zero.
To quote the Javadoc:
Returns a negative integer, zero, or a positive integer as this object is less than, equal to, or greater than the specified object.
So change your test to check every single possibility to see how the String#compareTo implementation’s behavior does not match your expectations. Make four checks, for equals zero, greater than zero, less than zero, and a fall-through to catch if you ever mistype the first three.
By the way, variable names should start with a lowercase letter, per Java naming conventions. So x, not X.
int comparison = x.compareTo( y ) ;
if ( comparison == 0 ) {
…
} else if ( comparison > 0 ) {
…
} else if ( comparison < 0 ) {
…
} else {
… Oops, the “if” tests must be flawed. We should never reach this point.
}

Problem with how does loops and Math.abs work [duplicate]

This code:
System.out.println(Math.abs(Integer.MIN_VALUE));
Returns -2147483648
Should it not return the absolute value as 2147483648 ?
Integer.MIN_VALUE is -2147483648, but the highest value a 32 bit integer can contain is +2147483647. Attempting to represent +2147483648 in a 32 bit int will effectively "roll over" to -2147483648. This is because, when using signed integers, the two's complement binary representations of +2147483648 and -2147483648 are identical. This is not a problem, however, as +2147483648 is considered out of range.
For a little more reading on this matter, you might want to check out the Wikipedia article on Two's complement.
The behaviour you point out is indeed, counter-intuitive. However, this behaviour is the one specified by the javadoc for Math.abs(int):
If the argument is not negative, the argument is returned.
If the argument is negative, the negation of the argument is returned.
That is, Math.abs(int) should behave like the following Java code:
public static int abs(int x){
if (x >= 0) {
return x;
}
return -x;
}
That is, in the negative case, -x.
According to the JLS section 15.15.4, the -x is equal to (~x)+1, where ~ is the bitwise complement operator.
To check whether this sounds right, let's take -1 as example.
The integer value -1 is can be noted as 0xFFFFFFFF in hexadecimal in Java (check this out with a println or any other method). Taking -(-1) thus gives:
-(-1) = (~(0xFFFFFFFF)) + 1 = 0x00000000 + 1 = 0x00000001 = 1
So, it works.
Let us try now with Integer.MIN_VALUE . Knowing that the lowest integer can be represented by 0x80000000, that is, the first bit set to 1 and the 31 remaining bits set to 0, we have:
-(Integer.MIN_VALUE) = (~(0x80000000)) + 1 = 0x7FFFFFFF + 1
= 0x80000000 = Integer.MIN_VALUE
And this is why Math.abs(Integer.MIN_VALUE) returns Integer.MIN_VALUE. Also note that 0x7FFFFFFF is Integer.MAX_VALUE.
That said, how can we avoid problems due to this counter-intuitive return value in the future?
We could, as pointed out by #Bombe, cast our ints to long before. We, however, must either
cast them back into ints, which does not work because
Integer.MIN_VALUE == (int) Math.abs((long)Integer.MIN_VALUE).
Or continue with longs somehow hoping that we'll never call Math.abs(long) with a value equal to Long.MIN_VALUE, since we also have Math.abs(Long.MIN_VALUE) == Long.MIN_VALUE.
We can use BigIntegers everywhere, because BigInteger.abs() does indeed always return a positive value. This is a good alternative, though a bit slower than manipulating raw integer types.
We can write our own wrapper for Math.abs(int), like this:
/**
* Fail-fast wrapper for {#link Math#abs(int)}
* #param x
* #return the absolute value of x
* #throws ArithmeticException when a negative value would have been returned by {#link Math#abs(int)}
*/
public static int abs(int x) throws ArithmeticException {
if (x == Integer.MIN_VALUE) {
// fail instead of returning Integer.MAX_VALUE
// to prevent the occurrence of incorrect results in later computations
throw new ArithmeticException("Math.abs(Integer.MIN_VALUE)");
}
return Math.abs(x);
}
Use a integer bitwise AND to clear the high bit, ensuring that the result is non-negative: int positive = value & Integer.MAX_VALUE (essentially overflowing from Integer.MAX_VALUE to 0 instead of Integer.MIN_VALUE)
As a final note, this problem seems to be known for some time. See for example this entry about the corresponding findbugs rule.
Here is what Java doc says for Math.abs() in javadoc:
Note that if the argument is equal to
the value of Integer.MIN_VALUE, the
most negative representable int value,
the result is that same value, which
is negative.
To see the result that you are expecting, cast Integer.MIN_VALUE to long:
System.out.println(Math.abs((long) Integer.MIN_VALUE));
There is a fix to this in Java 15 will be a method to int and long. They will be present on the classes
java.lang.Math and java.lang.StrictMath
The methods.
public static int absExact(int a)
public static long absExact(long a)
If you pass
Integer.MIN_VALUE
OR
Long.MIN_VALUE
A Exception is thrown.
https://bugs.openjdk.java.net/browse/JDK-8241805
I would like to see if either Long.MIN_VALUE or Integer.MIN_VALUE is passed a positive value would be return and not a exception but.
2147483648 cannot be stored in an integer in java, its binary representation is the same as -2147483648.
But (int) 2147483648L == -2147483648 There is one negative number which has no positive equivalent so there is not positive value for it. You will see the same behaviour with Long.MAX_VALUE.
Math.abs doesn't work all the time with big numbers I use this little code logic that I learnt when I was 7 years old!
if(Num < 0){
Num = -(Num);
}

Finding absolute value of a number without using Math.abs()

Is there any way to find the absolute value of a number without using the Math.abs() method in java.
If you look inside Math.abs you can probably find the best answer:
Eg, for floats:
/*
* Returns the absolute value of a {#code float} value.
* If the argument is not negative, the argument is returned.
* If the argument is negative, the negation of the argument is returned.
* Special cases:
* <ul><li>If the argument is positive zero or negative zero, the
* result is positive zero.
* <li>If the argument is infinite, the result is positive infinity.
* <li>If the argument is NaN, the result is NaN.</ul>
* In other words, the result is the same as the value of the expression:
* <p>{#code Float.intBitsToFloat(0x7fffffff & Float.floatToIntBits(a))}
*
* #param a the argument whose absolute value is to be determined
* #return the absolute value of the argument.
*/
public static float abs(float a) {
return (a <= 0.0F) ? 0.0F - a : a;
}
Yes:
abs_number = (number < 0) ? -number : number;
For integers, this works fine (except for Integer.MIN_VALUE, whose absolute value cannot be represented as an int).
For floating-point numbers, things are more subtle. For example, this method -- and all other methods posted thus far -- won't handle the negative zero correctly.
To avoid having to deal with such subtleties yourself, my advice would be to stick to Math.abs().
Like this:
if (number < 0) {
number *= -1;
}
Since Java is a statically typed language, I would expect that a abs-method which takes an int returns an int, if it expects a float returns a float, for a Double, return a Double. Maybe it could return always the boxed or unboxed type for doubles and Doubles and so on.
So you need one method per type, but now you have a new problem: For byte, short, int, long the range for negative values is 1 bigger than for positive values.
So what should be returned for the method
byte abs (byte in) {
// #todo
}
If the user calls abs on -128? You could always return the next bigger type so that the range is guaranteed to fit to all possible input values. This will lead to problems for long, where no normal bigger type exists, and make the user always cast the value down after testing - maybe a hassle.
The second option is to throw an arithmetic exception. This will prevent casting and checking the return type for situations where the input is known to be limited, such that X.MIN_VALUE can't happen. Think of MONTH, represented as int.
byte abs (byte in) throws ArithmeticException {
if (in == Byte.MIN_VALUE) throw new ArithmeticException ("abs called on Byte.MIN_VALUE");
return (in < 0) ? (byte) -in : in;
}
The "let's ignore the rare cases of MIN_VALUE" habit is not an option. First make the code work - then make it fast. If the user needs a faster, but buggy solution, he should write it himself.
The simplest solution that might work means: simple, but not too simple.
Since the code doesn't rely on state, the method can and should be made static. This allows for a quick test:
public static void main (String args []) {
System.out.println (abs(new Byte ( "7")));
System.out.println (abs(new Byte ("-7")));
System.out.println (abs((byte) 7));
System.out.println (abs((byte) -7));
System.out.println (abs(new Byte ( "127")));
try
{
System.out.println (abs(new Byte ("-128")));
}
catch (ArithmeticException ae)
{
System.out.println ("Integer: " + Math.abs (new Integer ("-128")));
}
System.out.println (abs((byte) 127));
System.out.println (abs((byte) -128));
}
I catch the first exception and let it run into the second, just for demonstration.
There is a bad habit in programming, which is that programmers care much more for fast than for correct code. What a pity!
If you're curious why there is one more negative than positive value, I have a diagram for you.
Although this shouldn't be a bottle neck as branching issues on modern processors isn't normally a problem, but in the case of integers you could go for a branch-less solution as outlined here: http://graphics.stanford.edu/~seander/bithacks.html#IntegerAbs.
(x + (x >> 31)) ^ (x >> 31);
This does fail in the obvious case of Integer.MIN_VALUE however, so this is a use at your own risk solution.
In case of the absolute value of an integer x without using Math.abs(), conditions or bit-wise operations, below could be a possible solution in Java.
(int)(((long)x*x - 1)%(double)x + 1);
Because Java treats a%b as a - a/b * b, the sign of the result will be same as "a" no matter what sign of "b" is; (x*x-1)%x will equal abs(x)-1; type casting of "long" is to prevent overflow and double allows dividing by zero.
Again, x = Integer.MIN_VALUE will cause overflow due to subtracting 1.
You can use :
abs_num = (num < 0) ? -num : num;
Here is a one-line solution that will return the absolute value of a number:
abs_number = (num < 0) ? -num : num;
-num will equal to num for Integer.MIN_VALUE as
Integer.MIN_VALUE = Integer.MIN_VALUE * -1
Lets say if N is the number for which you want to calculate the absolute value(+ve number( without sign))
if (N < 0)
{
N = (-1) * N;
}
N will now return the Absolute value

What do the return values of Comparable.compareTo mean in Java?

What is the difference between returning 0, returning 1 and returning -1 in compareTo() in Java?
Official Definition
From the reference docs of Comparable.compareTo(T):
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.
The implementor must ensure
sgn(x.compareTo(y)) ==
-sgn(y.compareTo(x)) for all x and y. (This implies that x.compareTo(y) must
throw an exception iff y.compareTo(x)
throws an exception.)
The implementor must also ensure that
the relation is transitive:
(x.compareTo(y)>0 && y.compareTo(z)>0)
implies x.compareTo(z)>0.
Finally, the implementor must ensure
that x.compareTo(y)==0 implies that
sgn(x.compareTo(z)) ==
sgn(y.compareTo(z)), for all z.
It is strongly recommended, but not
strictly required that
(x.compareTo(y)==0) == (x.equals(y)).
Generally speaking, any class that
implements the Comparable interface
and violates this condition should
clearly indicate this fact. The
recommended language is "Note: this
class has a natural ordering that is
inconsistent with equals."
In the foregoing description, the
notation sgn(expression) designates
the mathematical signum function,
which is defined to return one of -1,
0, or 1 according to whether the value
of expression is negative, zero or
positive.
My Version
In short:
this.compareTo(that)
returns
a negative int if this < that
0 if this == that
a positive int if this > that
where the implementation of this method determines the actual semantics of < > and == (I don't mean == in the sense of java's object identity operator)
Examples
"abc".compareTo("def")
will yield something smaller than 0 as abc is alphabetically before def.
Integer.valueOf(2).compareTo(Integer.valueOf(1))
will yield something larger than 0 because 2 is larger than 1.
Some additional points
Note: It is good practice for a class that implements Comparable to declare the semantics of it's compareTo() method in the javadocs.
Note: you should read at least one of the following:
the Object Ordering section of
the Collection Trail in the Sun Java
Tutorial
Effective Java by
Joshua Bloch, especially item 12:
Consider implementing Comparable
Java Generics and Collections by
Maurice Naftalin, Philip Wadler, chapter 3.1: Comparable
Warning: you should never rely on the return values of compareTo being -1, 0 and 1. You should always test for x < 0, x == 0, x > 0, respectively.
I use this mnemonic :
a.compareTo(b) < 0 // a < b
a.compareTo(b) > 0 // a > b
a.compareTo(b) == 0 // a == b
You keep the signs and always compare the result of compareTo() to 0
Answer in short: (search your situation)
1.compareTo(0) (return: 1)
1.compareTo(1) (return: 0)
0.comapreTo(1) (return: -1)
take example if we want to compare "a" and "b", i.e ("a" == this)
negative int if a < b
if a == b
Positive int if a > b
It can be used for sorting, and 0 means "equal" while -1, and 1 means "less" and "more (greater)".
Any return value that is less than 0 means that left operand is lesser, and if value is bigger than 0 then left operand is bigger.
int x = thisObject.compareTo(anotherObject);
The compareTo() method returns an int with the following characteristics:
negative If thisObject < anotherObject
zero If thisObject == anotherObject
positive If thisObject > anotherObject
System.out.println(A.compareTo(B)>0?"Yes":"No")
if the value of A>B it will return "Yes" or "No".

Categories