BigInteger in Java - java

I try using BigInteger like this (where m and n are integers):
m.substract(BigInteger.ONE), n.substract(BigInteger.ONE)
it says: "cannot invoke subtract(BigInteger) on the primitive type int"
What am I doing wrong here?

int is a native datatype, it is not an object!!!
Maybe you should declare m and n as BigIntegers instead?

m.substract(BigInteger.ONE) here m is only an int it is neither a BigInteger nor an Object of any kind, but a primitive. If you want to call a method (substract(BigInteger i)) then m and n need to be an Object of some class that actually has the method substract(BigInteger i).
You could do it like this:
BigInteger mBig = new BigInteger(m); // in this case n is a String
mBig = mBig.subtract(BigInteger.ONE);
BTW: it is called subtract and not substract (without the s)

ints are primitive times, they do not have methods.
The boxed type, Integer doesn't have a subract(BigInteger) method either.
You need to either make the ints into BigIntegers with BigInteger.valueOf or make the BigIntegers into ints with intValue.
The latter approach is unsafe as the BigInteger may be bigger than Integer.MAX_VALUE.
So you need to do
BigInteger.valueOf(m).subtract(BigInteger.ONE),
BigInteger.valueOf(n).subtract(BigInteger.ONE)
But this is a little messy so why not do
BigInteger.valueOf(m - 1), BigInteger.valueOf(n - 1)

Related

Recursion sum with generics [duplicate]

I have two Numbers. Eg:
Number a = 2;
Number b = 3;
//Following is an error:
Number c = a + b;
Why arithmetic operations are not supported on Numbers? Anyway how would I add these two numbers in java? (Of course I'm getting them from somewhere and I don't know if they are Integer or float etc).
You say you don't know if your numbers are integer or float... when you use the Number class, the compiler also doesn't know if your numbers are integers, floats or some other thing. As a result, the basic math operators like + and - don't work; the computer wouldn't know how to handle the values.
START EDIT
Based on the discussion, I thought an example might help. Computers store floating point numbers as two parts, a coefficient and an exponent. So, in a theoretical system, 001110 might be broken up as 0011 10, or 32 = 9. But positive integers store numbers as binary, so 001110 could also mean 2 + 4 + 8 = 14. When you use the class Number, you're telling the computer you don't know if the number is a float or an int or what, so it knows it has 001110 but it doesn't know if that means 9 or 14 or some other value.
END EDIT
What you can do is make a little assumption and convert to one of the types to do the math. So you could have
Number c = a.intValue() + b.intValue();
which you might as well turn into
Integer c = a.intValue() + b.intValue();
if you're willing to suffer some rounding error, or
Float c = a.floatValue() + b.floatValue();
if you suspect that you're not dealing with integers and are okay with possible minor precision issues. Or, if you'd rather take a small performance blow instead of that error,
BigDecimal c = new BigDecimal(a.floatValue()).add(new BigDecimal(b.floatValue()));
It would also work to make a method to handle the adding for you. Now I do not know the performance impact this will cause but I assume it will be less than using BigDecimal.
public static Number addNumbers(Number a, Number b) {
if(a instanceof Double || b instanceof Double) {
return a.doubleValue() + b.doubleValue();
} else if(a instanceof Float || b instanceof Float) {
return a.floatValue() + b.floatValue();
} else if(a instanceof Long || b instanceof Long) {
return a.longValue() + b.longValue();
} else {
return a.intValue() + b.intValue();
}
}
The only way to correctly add any two types of java.lang.Number is:
Number a = 2f; // Foat
Number b = 3d; // Double
Number c = new BigDecimal( a.toString() ).add( new BigDecimal( b.toString() ) );
This works even for two arguments with a different number-type. It will (should?) not produce any sideeffects like overflows or loosing precision, as far as the toString() of the number-type does not reduce precision.
java.lang.Number is just the superclass of all wrapper classes of primitive types (see java doc). Use the appropriate primitive type (double, int, etc.) for your purpose, or the respective wrapper class (Double, Integer, etc.).
Consider this:
Number a = 1.5; // Actually Java creates a double and boxes it into a Double object
Number b = 1; // Same here for int -> Integer boxed
// What should the result be? If Number would do implicit casts,
// it would behave different from what Java usually does.
Number c = a + b;
// Now that works, and you know at first glance what that code does.
// Nice explicit casts like you usually use in Java.
// The result is of course again a double that is boxed into a Double object
Number d = a.doubleValue() + (double)b.intValue();
Use the following:
Number c = a.intValue() + b.intValue(); // Number is an object and not a primitive data type.
Or:
int a = 2;
int b = 3;
int c = 2 + 3;
I think there are 2 sides to your question.
Why is operator+ not supported on Number?
Because the Java language spec. does not specify this, and there is no operator overloading. There is also not a compile-time natural way to cast the Number to some fundamental type, and there is no natural add to define for some type of operations.
Why are basic arithmic operations not supported on Number?
(Copied from my comment:)
Not all subclasses can implement this in a way you would expect. Especially with the Atomic types it's hard to define a usefull contract for e.g. add.
Also, a method add would be trouble if you try to add a Long to a Short.
If you know the Type of one number but not the other it is possible to do something like
public Double add(Double value, Number increment) {
return value + Double.parseDouble(increment.toString());
}
But it can be messy, so be aware of potential loss of accuracy and NumberFormatExceptions
Number is an abstract class which you cannot make an instance of. Provided you have a correct instance of it, you can get number.longValue() or number.intValue() and add them.
First of all, you should be aware that Number is an abstract class. What happens here is that when you create your 2 and 3, they are interpreted as primitives and a subtype is created (I think an Integer) in that case. Because an Integer is a subtype of Number, you can assign the newly created Integer into a Number reference.
However, a number is just an abstraction. It could be integer, it could be floating point, etc., so the semantics of math operations would be ambiguous.
Number does not provide the classic map operations for two reasons:
First, member methods in Java cannot be operators. It's not C++. At best, they could provide an add()
Second, figuring out what type of operation to do when you have two inputs (e.g., a division of a float by an int) is quite tricky.
So instead, it is your responsibility to make the conversion back to the specific primitive type you are interested in it and apply the mathematical operators.
The best answer would be to make util with double dispatch drilling down to most known types (take a look at Smalltalk addtition implementation)

How To Make My Own Way To Create An Object?

Objects like Integer, String, T[] all have their own unique constructor call. For example, when creating an Integer, instead of putting Integer i = new Integer(5), you can instead put Integer i = 5. Same for String and arrays. I want to know if I could make my own unique replacement for constructor calls. I have a class called Fraction, where you put a numerator and denominator, and it can do whatever a fraction can do. Right now, this is how I construct it: Fraction f = new Fraction(3, 4), where the numerator is the first argument and the denominator is the second. I'm wondering if I could do something like Fraction f = 3/4, where I don't have to call the constructor. Thanks!
You can't add your own literals. The best you could do is a function that parses a literal string.
Fraction f = fraction("3/4");
3/4 will always be the compile-time constant int 0.

how to cast return of generic method in java?

public num sum (num x , num y )
{
String out = (stringSum(String.valueOf(x),String.valueOf(y)));
return ??
}
what should i write for return to cast out String to num (Like Integer , Float and ... )
It looks like a use case for generics: https://docs.oracle.com/javase/tutorial/java/generics/types.html .
Make sure you understand well how it works, it behaves a bi differently than it may appear. I recommend reading this article several times :) - https://www.oracle.com/technetwork/java/javase/generics-tutorial-159168.pdf .
To convert a String to a number you can use Integer.parseInt(out) or Float.parseFloat(out) (or similar functions for the other types of numbers).
You cannot convert to a generic 'num' directly. You have to know which type you want to get.
You can use Number as return type though, because both ints and floats (and doubles, bytes, short and longs) are subtypes of Number.

BigInteger Modulo '%' Operation & Less Than / More Than Operations

Hi I have an algorithm in which I need to apply operations to BigInt's.
I understand that BigInt's can be manipulated using the Maths class such as:
import java.math.*;
BigInteger a;
BigInteger b = BigInteger.ZERO;
BigInteger c = BigInteger.ONE;
BigInteger d = new BigInteger ("3");
BigInteger e = BigInteger.valueOf(5);
a.multiply(b);
a.add(b);
a.substract(b);
a.divide(b);
I need to be able to apply greater than for a while condition e.g.
while (a > 0) {
Which gives me a syntax error saying "bad operand types for binary operator '>', first type: java.math.BigInteger, second type: int.
I also need to be able to apply the modulo (%) operator to a BigInteger.
b = a % c;
Can anyone suggest a way of doing this?
If there isn't a solution then I'm just going to have to somehow manipulate my BigInteger into an unique Long using a reduce function (which is far from ideal).
Silverzx.
To compare BigInteger, use BigInteger.compareTo.
while(a.compareTo(BigInteger.ZERO) > 0)
//...
And for modulo (%), use BigInteger.mod.
BigInteger blah = a.mod(b);
For comparing BigIntegers you may use compareTo, but in the special case when you compare to 0 the signum method will also do the job(and may be a bit faster). As for taking the remainder of a given division you may use the method mod(better option here) or alternatively use divideAndRemainder which returns an array with both the result of the division and the remainder.

Casting result of multiplication two positive integers to long is negative value

I have code like this :
int a = 629339;
int b = 4096;
long res = a*b;
The result is -1717194752
but if I add one manual cast to long long res = ((long)a)*b; or long res = (long) a*b; the result is correct 2577772544
Who can explain how does it works.
You have to break the assignment statement into its parts to understand what is doing on:
long res = a*b;
Step 1 is to get the values of a and b.
Step 2 is to evaluate a * b. Since a and b are both ints, this is an int multiplication. So we multiply 629339 by 629339 which would be 2577772544.
Unfortunately, 2577772544 is larger than the largest possible Java int value ... so the multiplication operation silently overflows ... and we get -1717194752 instead.
Step 3 we assign the value of the RHS to the LHS. Since the RHS is int and the LHS is float, the JLS says we perform a primitive widening conversion ... which simply turns -1717194752 into a long with the same value. The widened value is then assigned to res.
To get the answer that you are expecting, we have to force multiplication to be performed using long arithmetic. For example:
long res = ((long) a) * b;
In this case, we have a multiplication of a long by an int, and this is handled by widening the int to a long and performing a long multiply. This no longer overflows (because 2577772544 is well below the largest long value), so when we finally assign the value to res, it is the number that you were expecting.
a*b is an integer, not a long.
Because it's only an integer, it has already wrapped around the 32-bit limit.
Casting this integer back to long will not magically recover that data.
long res = a*b;
a*b will be treated as integer unless you add 'l' at end (or) cast.
As per java tutorial
The int data type is a 32-bit signed two's complement integer. It has a minimum value of -2,147,483,648 and a maximum value of 2,147,483,647 (inclusive). For integral values, this data type is generally the default choice unless there is a reason (like the above) to choose something else.

Categories

Resources