I am trying to printout fibonacci series upto 'N' numbers. All works as per expectation till f(92) but when I am trying to get the value of f(93), values turns out in negative: "-6246583658587674878". How this could be possible? What is the mistake in the logic below?
public long fibo(int x){
long[] arr = new long[x+1];
arr[0]=0;
arr[1]=1;
for (int i=2; i<=x; i++){
arr[i]=arr[i-2]+arr[i-1];
}
return arr[x];
}
f(91) = 4660046610375530309
f(92) = 7540113804746346429
f(93) = -6246583658587674878
Is this because of data type? What else data type I should use for printing fibonacci series upto N numbers? N could be any integer within range [0..10,000,000].
You've encountered an integer overflow:
4660046610375530309 <-- term 91
+7540113804746346429 <-- term 92
====================
12200160415121876738 <-- term 93: the sum of the previous two terms
9223372036854775808 <-- maximum value a long can store
To avoid this, use BigInteger, which can deal with an arbitrary number of digits.
Here's your implementation converted to use BigDecimal:
public String fibo(int x){
BigInteger[] arr = new BigInteger[x+1];
arr[0]=BigInteger.ZERO;
arr[1]=BigInteger.ONE;
for (int i=2; i<=x; i++){
arr[i]=arr[i-2].add(arr[i-1]);
}
return arr[x].toString();u
}
Note that the return type must be String (or BigInteger) because even the modest value of 93 for x produces a result that is too great for any java primitive to represent.
This happened because the long type overflowed. In other words: the number calculated is too big to be represented as a long, and because of the two's complement representation used for integer types, after an overflow occurs the value becomes negative. To have a better idea of what's happening, look at this code:
System.out.println(Long.MAX_VALUE);
=> 9223372036854775807 // maximum long value
System.out.println(Long.MAX_VALUE + 1);
=> -9223372036854775808 // oops, the value overflowed!
The value of fibo(93) is 12200160415121876738, which clearly is greater than the maximum value that fits in a long.
This is the way integers work in a computer program, after all they're limited and can not be infinite. A possible solution would be to use BigInteger to implement the method (instead of long), it's a class for representing arbitrary-precision integers in Java.
As correctly said in above answers, you've experienced overflow, however with below java 8 code snippet you can print series.
Stream.iterate(new BigInteger[] {BigInteger.ZERO, BigInteger.ONE}, t -> new BigInteger[] {t[1], t[0].add(t[1])})
.limit(100)
.map(t -> t[0])
.forEach(System.out::println);
Related
I have some integers which I am adding using Arrays.stream(int arr[]).sum(). It returns the truncated sum in int while the actual sum is bigger and fits in long. why does the stream API returns only int by truncating it but not long?
Tried for small integers like int myArray[] = { 1, 5, 8 };
int sum = Arrays.stream(myArray).sum();
works fine.
but doesn't work for longer integers whose sum leads to long.
Scenario 1 below works fine and returns 14
int myArray[] = { 1, 5, 8 };
int sum = Arrays.stream(myArray).sum();
while scenario 2 won't work as sum is going beyond 32 bits. it gives sum as -105032716 while expected is 4189934580
int myArray[] = { 2094967290, 2094967290};
int sum = Arrays.stream(myArray).sum();
and to get the correct sum, if I do below I get the expected result 4189934580
long sum = 0L + 2094967290+2094967290;
System.out.println(sum);
This is something that's up to the developer. You know what to expect, what data you're dealing with, and, more importantly, you test it. In my opinion, this is not different from how we handle the possible overflow of any intOne + intTwo.
If you know that the sum will exceed the int range, then switch to a long stream (thanks to Carlos Heuberger for asLongStream() instead of mapToLong(i -> i)):
long sum = Arrays.stream(myArray).asLongStream().sum();
You are summing int(s) (a 32-bit primitive data type). If you want a long, sum long(s). This is how primitive math works.
int c = 2094967290 + 2094967290;
System.out.println(c);
is the same as
System.out.println(2094967290 + 2094967290);
Using long(s)
System.out.println(2094967290 + 2094967290L);
or with streams like this will yield the correct result here
long sum = Arrays.stream(myArray).mapToLong(Long::valueOf).sum();
or (as pointed out in the comments)
long sum = Arrays.stream(myArray).asLongStream().sum();
However, long can also overflow (it is a 64-bit primitive data type). For arbitrary precision, you should use BigInteger.
BigInteger sum = Arrays.stream(myArray).mapToObj(BigInteger::valueOf)
.reduce(BigInteger.ZERO, (a, b) -> a.add(b));
Why if I multiply int num = 2,147,483,647 by the same int num is it returning 1 as result? Note that I am in the limit of the int possible value.
I already try to catch the exception but still give the result as 1.
Before any multiplication java translates ints to binary numbers. So you are actually trying to multiply 01111111111111111111111111111111 by 01111111111111111111111111111111. The result of this is something like
1111111111111111111111111111111000000000000000000000000000000001. The int can hold just 32 bits, so in fact you get 00000000000000000000000000000001 which is =1 in decimal.
In integer arithmetic, Java doesn't throw an exception when an overflow occurs. Instead, it just the 32 least significant bits of the outcome, or equivalently, it "wraps around". That is, if you calculate 2147483647 + 1, the outcome is -2147483648.
2,147,483,647 squared happens to be, in binary:
11111111111111111111111111111100000000000000000000000000000001
The least significant 32 bits of the outcome are equal to the value 1.
If you want to calculate with values which don't fit in 32 bits, you have to use either long (if 64 bits are sufficient) or java.math.BigInteger (if not).
int cannot handle just any large value.Look here. In JAVA you have an exclusive class for this problem which comes quite handy
import java.math.BigInteger;
public class BigIntegerDemo {
public static void main(String[] args) {
BigInteger b1 = new BigInteger("987654321987654321000000000"); //change it to your number
BigInteger b2 = new BigInteger("987654321987654321000000000"); //change it to your number
BigInteger product = b1.multiply(b2);
BigInteger division = b1.divide(b2);
System.out.println("product = " + product);
System.out.println("division = " + division);
}
}
Source : Using BigInteger In JAVA
The Java Language Specification exactly rules what should happen in the given case.
If an integer multiplication overflows, then the result is the low-order bits of the mathematical product as represented in some sufficiently large two's-complement format. As a result, if overflow occurs, then the sign of the result may not be the same as the sign of the mathematical product of the two operand values.
It means, that when you multiply two ints, the result will be represented in a long value first (that type holds sufficient bits to represent the result). Then, because you assign it to an int variable, the lower bits are kept for your int.
The JLS also says:
Despite the fact that overflow, underflow, or loss of information may occur, evaluation of a multiplication operator * never throws a run-time exception.
That's why you never get an exception.
My guess: Store the result in a long, and check what happens if you downcast to int. For example:
int num = 2147483647;
long result = num * num;
if (result != (long)((int)result)) {
// overflow happened
}
To really follow the arithmetics, let's follow the calculation:
((2^n)-1) * ((2^n)-1) =
2^(2n) - 2^n - 2^n + 1 =
2^(2n) - 2^(n+1) + 1
In your case, n=31 (your number is 2^31 - 1). The result is 2^62 + 2^32 + 1. In bits it looks like this (split by the 32bit boundary):
01000000000000000000000000000001 00000000000000000000000000000001
From this number, you get the rightmost part, which equals to 1.
It seems that the issue is because the int can not handle such a large value. Based on this link from oracle regarding the primitive types, the maximum range of values allowed is 2^31 -1 (2,147,483,647) which is exactly the same value that you want to multiply.
So, in this case is recommended to use the next primitive type with greater capacity, for example you could change your "int" variables to "long" which have a bigger range between -2^63 to 2^63-1 (-9223372036854775808 to 9223372036854775807).
For example:
public static void main(String[] args) {
long num = 2147483647L;
long total = num * num;
System.out.println("total: " + total);
}
And the output is:
total: 4611686014132420609
I hope this can help you.
Regards.
According to this link, a Java 'int' signed is 2^31 - 1. Which is equal to 2,147,483,647.
So if you are already at the max for int, and if you multiply it by anything, I would expect an error.
I have this question that has completely stumped me.
I have to create a variable that equals Integer.MAX_VALUE... (in Java)
// The answer must contain balanced parentesis
public class Exercise{
public static void main(String [] arg){
[???]
assert (Integer.MAX_VALUE==i);
}
}
The challenge is that the source code cannot contain the words "Integer", "Float", "Double" or any digits (0 - 9).
Here's a succinct method:
int ONE = "x".length();
int i = -ONE >>> ONE; //unsigned shift
This works because the max integer value in binary is all ones, except the top (sign) bit, which is zero. But -1 in twos compliment binary is all ones, so by bit shifting -1 one bit to the right, you get the max value.
11111111111111111111111111111111 // -1 in twos compliment
01111111111111111111111111111111 // max int (2147483647)
As others have said.
int i = Integer.MAX_VALUE;
is what you want.
Integer.MAX_VALUE, is a "static constant" inside of the "wrapper class" Integer that is simply the max value. Many classes have static constants in them that are helpful.
Here's a solution:
int ONE = "X".length();
int max = ONE;
while (max < max + ONE) {
max = max + ONE;
}
or lots of variants.
(The trick you were missing is how to "create" an integer value without using a numeric literal or a number wrapper class. Once you have created ONE, the rest is simple ...)
A bit late, but here goes:
int two = "xx".length();
int thirtyone = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx".length();
System.out.println(Math.pow(two, thirtyone)-1);
How did I go? :p
I do like that bitshift one though...
The issue is that the answer cannot contain: "Integer", "Float", "Double", and digits (0 - 9)
There are other things in Java which can be represented as an Integer, for example a char:
char aCharacter = 'a';
int asInt = (int) aCharacter;
System.out.println(asInt); //Output: 97
You can also add chars together in this manner:
char aCharacter = 'a';
char anotherCharacter = 'b';
int sumOfCharacters = aCharacter + anotherCharacter;
System.out.println(sumOfCharacters); //Output: 195
With this information, you should be able to work out how to get to 2147483647on your own.
OK, so an Integer can only take certain values. This is from MIN_VALUE to MAX_VALUE where the minimum value is negative.
If you increase an integer past this upper bound the value will wrap around and become the lowest value possible. e.g. MAX_VALUE+1 = MIN_VALUE.
Equally, if you decrease an integer past the lower bound it will wrap around and become the largest possible value. e.g. MIN_VALUE-1 = MAX_VALUE.
Therefore a simple program that instantiates an int, decrements it until it wraps around and returns that value should give you the same value as Integer.MAX_VALUE
public static void main(String [] arg) {
int i = -1
while (i<0) {
i--;
}
System.out.println(i);
}
I've been experimenting with Python as a begninner for the past few hours. I wrote a recursive function, that returns recurse(x) as x! in Python and in Java, to compare the two. The two pieces of code are identical, but for some reason, the Python one works, whereas the Java one does not. In Python, I wrote:
x = int(raw_input("Enter: "))
def recurse(num):
if num != 0:
num = num * recurse(num-1)
else:
return 1
return num
print recurse(x)
Where variable num multiplies itself by num-1 until it reaches 0, and outputs the result. In Java, the code is very similar, only longer:
public class Default {
static Scanner input = new Scanner(System.in);
public static void main(String[] args){
System.out.print("Enter: ");
int x = input.nextInt();
System.out.print(recurse(x));
}
public static int recurse(int num){
if(num != 0){
num = num * recurse(num - 1);
} else {
return 1;
}
return num;
}
}
If I enter 25, the Python Code returns 1.5511x10E25, which is the correct answer, but the Java code returns 2,076,180,480, which is not the correct answer, and I'm not sure why.
Both codes go about the same process:
Check if num is zero
If num is not zero
num = num multiplied by the recursion of num - 1
If num is zero
Return 1, ending that stack of recurse calls, and causing every returned num to begin multiplying
return num
There are no brackets in python; I thought that somehow changed things, so I removed brackets from the Java code, but it didn't change. Changing the boolean (num != 0) to (num > 0 ) didn't change anything either. Adding an if statement to the else provided more context, but the value was still the same.
Printing the values of num at every point gives an idea of how the function goes wrong:
Python:
1
2
6
24
120
720
5040
40320
362880
3628800
39916800
479001600
6227020800
87178291200
1307674368000
20922789888000
355687428096000
6402373705728000
121645100408832000
2432902008176640000
51090942171709440000
1124000727777607680000
25852016738884976640000
620448401733239439360000
15511210043330985984000000
15511210043330985984000000
A steady increase. In the Java:
1
2
6
24
120
720
5040
40320
362880
3628800
39916800
479001600
1932053504
1278945280
2004310016
2004189184
-288522240
-898433024
109641728
-2102132736
-1195114496
-522715136
862453760
-775946240
2076180480
2076180480
Not a steady increase. In fact, num is returning negative numbers, as though the function is returning negative numbers, even though num shouldn't get be getting below zero.
Both Python and Java codes are going about the same procedure, yet they are returning wildly different values. Why is this happening?
Two words - integer overflow
While not an expert in python, I assume it may expand the size of the integer type according to its needs.
In Java, however, the size of an int type is fixed - 32bit, and since int is signed, we actually have only 31 bits to represent positive numbers. Once the number you assign is bigger than the maximum, it overflows the int (which is - there is no place to represent the whole number).
While in the C language the behavior in such case is undefined, in Java it is well defined, and it just takes the least 4 bytes of the result.
For example:
System.out.println(Integer.MAX_VALUE + 1);
// Integer.MAX_VALUE = 0x7fffffff
results in:
-2147483648
// 0x7fffffff + 1 = 0x800000000
Edit
Just to make it clearer, here is another example. The following code:
int a = 0x12345678;
int b = 0x12345678;
System.out.println("a*b as int multiplication (overflown) [DECIMAL]: " + (a*b));
System.out.println("a*b as int multiplication (overflown) [HEX]: 0x" + Integer.toHexString(a*b));
System.out.println("a*b as long multiplication (overflown) [DECIMAL]: " + ((long)a*b));
System.out.println("a*b as long multiplication (overflown) [HEX]: 0x" + Long.toHexString((long)a*b));
outputs:
a*b as int multiplication (overflown) [DECIMAL]: 502585408
a*b as int multiplication (overflown) [HEX]: 0x1df4d840
a*b as long multiplication (overflown) [DECIMAL]: 93281312872650816
a*b as long multiplication (overflown) [HEX]: 0x14b66dc1df4d840
And you can see that the second output is the least 4 bytes of the 4 output
Unlike Java, Python has built-in support for long integers of unlimited precision. In Java, an integer is limited to 32 bit and will overflow.
As other already wrote, you get overflow; the numbers simply won't fit within java's datatype representation. Python has a built-in capability of bignum as to where java has not.
Try some smaller values and you will see you java-code works fine.
Java's int range
int
4 bytes, signed (two's complement). -2,147,483,648 to 2,147,483,647. Like all numeric types ints may be cast into other numeric types (byte, short, long, float, double). When lossy casts are done (e.g. int to byte) the conversion is done modulo the length of the smaller type.
Here the range of int is limited
The problem is very simple ..
coz in java the max limit of integer is 2147483647 u can print it by System.out.println(Integer.MAX_VALUE);
and minimum is System.out.println(Integer.MIN_VALUE);
Because in the java version you store the number as an int which I believe is 32-bit. Consider the biggest (unsigned) number you can store with two bits in binary: 11 which is the number 3 in decimal. The biggest number that can be stored four bits in binary is 1111 which is the number 15 in decimal. A 32-bit (signed) number cannot store anything bigger than 2,147,483,647. When you try to store a number bigger than this it suddenly wraps back around and starts counting up from the negative numbers. This is called overflow.
If you want to try storing bigger numbers, try long.
I have an array of ints ie. [1,2,3,4,5] . Each row corresponds to decimal value, so 5 is 1's, 4 is 10's, 3 is 100's which gives value of 12345 that I calculate and store as long.
This is the function :
public long valueOf(int[]x) {
int multiplier = 1;
value = 0;
for (int i=x.length-1; i >=0; i--) {
value += x[i]*multiplier;
multiplier *= 10;
}
return value;
}
Now I would like to check if value of other int[] does not exceed long before I will calculate its value with valueOf(). How to check it ?
Should I use table.length or maybe convert it to String and send to
public Long(String s) ?
Or maybe just add exception to throw in the valueOf() function ?
I hope you know that this is a horrible way to store large integers: just use BigInteger.
But if you really want to check for exceeding some value, just make sure the length of the array is less than or equal to 19. Then you could compare each cell individually with the value in Long.MAX_VALUE. Or you could just use BigInteger.
Short answer: All longs fit in 18 digits. So if you know that there are no leading zeros, then just check x.length<=18. If you might have leading zeros, you'll have to loop through the array to count how many and adjust accordingly.
A flaw to this is that some 19-digit numbers are valid longs, namely those less than, I believe it comes to, 9223372036854775807. So if you wanted to be truly precise, you'd have to say length>19 is bad, length<19 is good, length==19 you'd have to check digit-by-digit. Depending on what you're up to, rejecting a subset of numbers that would really work might be acceptable.
As others have implied, the bigger question is: Why are you doing this? If this is some sort of data conversion where you're getting numbers as a string of digits from some external source and need to convert this to a long, cool. If you're trying to create a class to handle numbers bigger than will fit in a long, what you're doing is both inefficient and unnecessary. Inefficient because you could pack much more than one decimal digit into an int, and doing so would give all sorts of storage and performance improvements. Unnecessary because BigInteger already does this. Why not just use BigInteger?
Of course if it's a homework problem, that's a different story.
Are you guaranteed that every value of x will be nonnegative?
If so, you could do this:
public long valueOf(int[]x) {
int multiplier = 1;
long value = 0; // Note that you need the type here, which you did not have
for (int i=x.length-1; i >=0; i--) {
next_val = x[i]*multiplier;
if (Long.MAX_LONG - next_val < value) {
// Error-handling code here, however you
// want to handle this case.
} else {
value += next_val
}
multiplier *= 10;
}
return value;
}
Of course, BigInteger would make this much simpler. But I don't know what your problem specs are.