Why am I getting negative numbers in this array? - java

I just started learning arrays so please explain in layman's terms if you can.
At around the 50th term of the array, negative numbers start appearing, which seems nonsensical given the code. I'm running this using eclipse (latest version as of 12/19).
public class Array1
{
/*
* #param args
*/
public static void main(String[] args)
{
// TODO Auto-generated method stub
int[] tree = new int[1000];
tree[0] = 1;
tree[1] = 2;
int j = 0;
for (j = 1; j<999; j++)
{
tree[j+1] = tree[j] + tree[j-1];
}
for (int i=1; i<=150; i++)
{
System.out.println(tree[i]);
}
}
}

What you are computing is the sequence of Fibonacci numbers which are know to grow exponentially. Therefore, you eventually overflow your int, which causes it to become negative.

Integer overflow computing fibonacci numbers.
Read this article
int: 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).

Related

C(n,r) calculator program doesn't work

I made a C(n,r) calculator using java Netbeans JFrameform.
here is the frame
Here is the code :-
private void lllActionPerformed(java.awt.event.ActionEvent evt) {
int n=Integer.parseInt(t1.getText());
int r=Integer.parseInt(t2.getText());
int s=1;
for(int i=1;i<=n;i=i+1){
s=i*s;
}
int p=1;
for(int j=1;j<=n-r;j=j+1){
p=j*p;
}
int q=1;
for(int k=1;k<=r;k=k+1){
q=k*q;
}
int re=s/(p*q);
t3.setText(" "+re);
}
the code works well for values values of n upto 12. But for 13 and onward , code starts giving wrong answer.
wrong output
why is this happening? Your help is appreciated.
During the calculations the value goes over Integer.MAX_VALUE This is an overflow of arithmetic operation:
Integer overflow can be demonstrated through an odometer overflowing, a mechanical version of the phenomenon. All digits are set to the maximum 9 and the next increment of the white digit causes a cascade of carry-over additions setting all digits to 0, but there is no higher digit to change to a 1, so the counter resets to zero. This is wrapping in contrast to saturating.
In computer programming, an integer overflow occurs when an arithmetic operation attempts to create a numeric value that is outside of the range that can be represented with a given number of bits – either larger than the maximum or lower than the minimum representable value.
Try to replace int with long values. It will work with a greater value.
private void lllActionPerformed(java.awt.event.ActionEvent evt) {
int n=Integer.parseInt(t1.getText());
int r=Integer.parseInt(t2.getText());
int s=1;
for(int i=1;i<=n;i=i+1){
s=i*s;
}
long p=1L;
for(int j=1;j<=n-r;j=j+1){
p=j*p;
}
long q=1L;
for(int k=1;k<=r;k=k+1){
q=k*q;
}
long re=s/(p*q);
t3.setText(" "+re);
}
With 14 and 2 as inputs the result is 91.
If you want to have a correct result for big values you have to use a BigInteger that handle:
Immutable arbitrary-precision integers
Try using this
private void lllActionPerformed(java.awt.event.ActionEvent evt) {
int n=Integer.parseInt(t1.getText());
int r=Integer.parseInt(t2.getText());
if (r > n / 2) r = n - r; // because C(n, r) == C(n, n - r)
long ans = 1;
int i;
for (i = 1; i <= r; i++) {
ans *= n - r + i;
ans /= i;
}
t3.setText(" "+ans);
}

Why am i getting negative numbers in Fibonacci series using java

I have written this code to get Fibonacci numbers by inputting the size.
The results i am getting is correct but only thing i am concerned about is the negative sign for some values for higher range of size input.
1- I am unable to find the flaw in the code, how can i get rid of the negative values in the output.?
2- Why after some negative values there are positive values.
3- First negative value is -1323752223 then a positive number follows.
Thank you.
Here is the code:
import java.util.Scanner;
public class FibonacciSeries {
public static void main(String[] args) {
// TODO Auto-generated method stub
int a, c = 0;
int result = 0;
int b = 1;
Scanner scan = new Scanner(System.in);
System.out.println("Enter the Number to display Fibonacci Series");
a = scan.nextInt();
System.out.println("Fibonacci Seriers is as follows");
for (int i = 1; i <= a; i++) {
System.out.print(" "+result+" ");
result = c + b;
b = c;
c = result;
}
}
}
Depending on the input value, you likely exceeding the max value that an integer can hold.
Integers are limited to 2^31-1, or 2,147,483,647. Once you reach that threshold, the number will wrap around and start with the minimum value, -2^31, or -2,147,483,648.
Also see Integer.MAX_VALUE.
Well, you can use 'if' for System.out.print to check if result is negative or positive. The reason why you are getting negative values is because int is "only" 32-bit long.
You can use long instead of int, which would make it a little bit better for Fib. sequence, but it won't solve your actual problem - negative numbers.
Here is the code:
for( int i = 1; i <= a; i ++ ) {
if( result >= 0 ) {
System.out.print(" " + result + " ");
}
result = c + b;
b = c;
c = result;
}
try to modify type of variables from 'int' to 'long int' or ' unsigned int'. Maybe high value modify the bit of sign.

count Number of 1 Bits in java

I encountered a strange problem while doing an leetcode problem. This is about bits representation in Java.
Write a function that takes an unsigned integer and returns the number of ’1' bits it has (also known as the Hamming weight).
For example, the 32-bit integer ’11' has binary representation 00000000000000000000000000001011, so the function should return 3.
My solution is
public class Solution {
// you need to treat n as an unsigned value
public int hammingWeight(int n) {
int count = 0;
for(int i = 0; i < 32; ++i){
if((n >>> i) % 2 == 1){
++count;
}
}
return count;
}
}
This code is not accepted because of the input case:
4294967295 (11111111111111111111111111111111)
I reviewed the bit representation of integer in java but still do not know the problem of the solution?
Could anyone help me?
public int hammingWeight(int n) {
return Integer.bitCount(n);
}
Integer.bitCount(int i)
Returns the number of one-bits in the two's complement binary
representation of the specified int value.
The issue is performing modulo when you want a bitwise &. Something like,
public static int hammingWeight(int n) {
int count = 0;
for (int i = 0; i < 32; ++i) {
if (((n >>> i) & 1) == 1) {
++count;
}
}
return count;
}
public static void main(String[] args) {
int c = -1;
System.out.println(hammingWeight(c));
}
Outputs (as expected)
32
Java uses twos compliment. So the negative bit is the far left one. That means if you have a number greater than Integer.MAX_VALUE your input will be a negative number. When you do %2the sign remains unchanged. An alternative would be to use &1which will change the sign bit. After the first iteration, and you have done a bit shift, the sign bit will be zero.

find a missing number using limited memory

The problem is, given an input file with four billion unique integers, provide an algorithm to generate an integer which is not contained in the file, assume only have 10 MB of memory.
Searched for some solutions and posted code below, one of which is to store integers into bit-vector blocks (each block representing a specific range of integers among 4 billion range, each bit in the block represent for an integer), and using another counter for each block, to count the number of integers in each block. So that if number of integers is less than the block capacity for integers, scan the bit-vector of the block to find which are missing integers.
My question for this solution is, why "the nearer to the middle that we pick, the less memory will be used at any given time", here are more context,
The array in the first pass can fit in 10 megabytes, or roughly 2^23 bytes, of memory. Since each element in the array is an int, and an int is 4 bytes, we can hold an array of at most about 2^21 elements. So, we can deduce the following:
Therefore, we can conclude the following:
2^10< rangeSize <2^26, and these conditions give us a good amount of "wiggle room," but the nearer to the middle that we pick, the less memory will be used at any given time.
public class QuestionB {
public static int bitsize = 1048576; // 2^20 bits (2^17 bytes)
public static int blockNum = 4096; // 2^12
public static byte[] bitfield = new byte[bitsize/8];
public static int[] blocks = new int[blockNum];
public static void findOpenNumber() throws FileNotFoundException {
int starting = -1;
Scanner in = new Scanner (new FileReader ("Chapter 10/Question10_3/input_file_q10_3.txt"));
while (in.hasNextInt()) {
int n = in.nextInt();
blocks[n / (bitfield.length * 8)]++;
}
for (int i = 0; i < blocks.length; i++) {
if (blocks[i] < bitfield.length * 8){
/* if value < 2^20, then at least 1 number is missing in
* that section. */
starting = i * bitfield.length * 8;
break;
}
}
in = new Scanner(new FileReader("Chapter 10/Question10_3/input_file_q10_3.txt"));
while (in.hasNextInt()) {
int n = in.nextInt();
/* If the number is inside the block that’s missing
* numbers, we record it */
if (n >= starting && n < starting + bitfield.length * 8) {
bitfield [(n-starting) / 8] |= 1 << ((n - starting) % 8);
}
}
for (int i = 0 ; i < bitfield.length; i++) {
for (int j = 0; j < 8; j++) {
/* Retrieves the individual bits of each byte. When 0 bit
* is found, finds the corresponding value. */
if ((bitfield[i] & (1 << j)) == 0) {
System.out.println(i * 8 + j + starting);
return;
}
}
}
}
public static void main(String[] args) throws FileNotFoundException {
findOpenNumber();
}
}
If you form M blocks each of size 2^32/M, the total memory required is M+2^27/M words (32 bits). This function reaches a minimum when M=√2^27, which is halfway between 1 and 2^27 blocks. The minimum is 2^14.5 words, about 92 KBytes.
This is very clear on a bilogarithmic plot.
I like this question. I'll give it additional thought but I think if disk space and time is not an issue, you can break the numbers into 100k blocks, and sort them in each file. Any block that doesn't have 100k entries will have a gap. It's not elegant at all but it gets the ball rolling.

Program gives same result every time when it should be random

The goal of this program is to take 2 random variables for a fraction and see if they are already in reduced terms or not. The supposed probability of this is 6/(pi^2). I run 1,000 different combinations of variables and determine how many were and were not already reduced. Then I solve for pi.
But the output is giving me "pi is 2.449489742783178" every time I run it.
Anyone know why? Thanks.
import java.util.*;
public class ratio1 {
/**
* #param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
int nonReducedCount = 0; //counts how many non reduced ratios there are
for(int i =1; i<=1000; i++){
Random rand = new Random();
int n = rand.nextInt(1000)+1; //random int creation
int m = rand.nextInt(1000)+1;
//Ratio ratio = new Ratio(n,m);
if (gcd(n,m)> 1 ){ // if the ratio was not already fully reduced
nonReducedCount++; // increase the count of non reduced ratios
}
}
int reducedCount = 1000 - nonReducedCount; //number of times the ratio was reduced already
double reducedRatio = reducedCount / nonReducedCount; //the ratio for reduced and not reduced
reducedRatio *= 6;
reducedRatio = Math.sqrt(reducedRatio);
System.out.println("pi is " + reducedRatio);
}
public static int gcd(int a, int b) { return b==0 ? a : gcd(b,a%b); }
}
When you divide two integers, you get integer division, with an integer result, even if you later assign the result to a double. Try
double reducedRatio = (double)reducedCount / nonReducedCount;
i.e. convert one of the operands to a double.

Categories

Resources