View Full Version : Error in a tiny Java app (math and arrays)
Yazon
10-15-2006, 08:07 AM
Hi all
My first post on these forums. I have enrolled into Java classes and got this problem that i have mostly figured out how to do, but my app gives me an error when i run it. I understand that there is a mistake, but i can't figure out what is causing it and if it can be fixed.
The app is from a Java texbook, and its purpose is to calculate sales comissions.
at $200 base + 9% of sales = salary.
I'm using an array to feed the sales figures, then trying to do the math upon the values of the array and count how many salesmen fit into the ranges of salaries between:
200-299
300-399
....
1000 and more.
Here is my code:
public class Salary
{
public static void main(String[] args)
{
double salary[]={300, 200, 600, 700, 2000, 8000, 800, 800, 900, 6000, 1100};
int frequency []= new int [11];
System.out.printf("%10s: %6s:\n","Range", "Frequency");
for (int range = 0; range < (salary.length); range++)
++frequency[(int)Math.floor(((salary[range]*(.9)+200)*.01))];
for (int range1 =2; range1<frequency.length; range1++)
System.out.printf("$%4d-%4d: %10d\n", range1*100,range1*100+9,frequency[range1]);
}
}
Error is :
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 20
at Salary.main(Salary.java:11)
I know that if i just feed the numbers without doing the math - the app seems to work, but when i start doing the math - it stops working. I'm using the Math.floor in order to get an integer value, which can then be pushed into the frequency array.
The frequency array should collect the values between 0 and 10 and then print them (as number of people) next to the range of salary
Ok, so as the error suggests you are trying to access an array index which is outside the bounds for that array. Take a look at the following code.
for (int range = 0; range < (salary.length); range++)
{
//Added this print statement so we can see why we're going out of bounds.
System.out.println((int)Math.floor(((salary[range]*(.9)+200)*.01)));
++frequency[(int)Math.floor(((salary[range]*(.9)+200)*.01))];
}
You declare frequency as an array of size 11; which means the valid indexes for that variable are frequency[0] to frequency[10].
If you run your code with the added print statement and look at the numbers that get printed out you'll see that it prints 4,3,7,8,20 which are the numbers that are computed by (int)Math.floor(((salary[range]*(.9)+200)*.01)) for each iteration of the for loop. The error occurs at the computed value of 20.
If we simplify your code that means you're doing the following in your for loop
++frequency[4]
++frequency[3]
++frequency[7]
++frequency[8]
++frequency[20]
20 is not a valid index of the frequency array. As I previously stated since the array has a length of 11, trying to access the array at an index greater than 10 will give an array out of bounds error.
This suggests to me that your computation logic is slightly off.
Good Luck.
Yazon
10-15-2006, 06:37 PM
So if i could handle all the values grater than 10 separately, for example by adding 1 to the index 10 (last index in the array frequency) for values greater than 1000. That should do by logic, now i wrote the way i thought it would need to work, but now the program completely skips the printing of all the ranges except for the very last one. And then it goes into infinite loop.
I've tried to read my own code line by line trying to figure out what would happen to every value as it is run through the code and it seems fine to me. On the other hand with my very limited programming knowledge i'm probably not seeing something obvious.
here is the new code:
public class Salary
{
public static void main(String[] args)
{
double salary[]={300, 200, 600, 700, 2000, 8000, 800, 800, 900, 6000, 1100};
int frequency []= new int [11];
System.out.printf("%10s: %6s:\n","Range", "Frequency");
for (int range = 0; range < (salary.length); range++)
{
if (10<=(int)Math.floor(((salary[range]*(.9)+200)*.01)))
++frequency[10];
else
// System.out.println((int)Math.floor(((salary[range]*(.9)+200)*.01)));
++frequency[(int)Math.floor(((salary[range]*(.9)+200)*.01))];
}
for (int range1 =2; range1<frequency.length; range1++)
System.out.printf("$%4d-%4d: %10d\n", range1*100,range1*100+9,frequency[range1]);
for (int range2 =10;range2<=frequency.length;)
System.out.printf("$%4d %4s: %10d\n", range2*100,"<=",frequency[range2]);
}
}
and it loops printing this line
$1000 <=: 5
Aradon
10-15-2006, 06:55 PM
You're going into an infinate loop here:
for (int range2 =10;range2<=frequency.length;)
System.out.printf("$%4d %4s: %10d\n", range2*100,"<=",frequency[range2]);
You do nothing to range2 so it never breaks out of the for loop (need something like a range2-- or range2++
I'm also confused what you are doing with frequence, as in what the purpose of it is.
-Aradon
Yazon
10-15-2006, 07:08 PM
Ahhh.. yes, i do need something for the range2 to move and not to loop.
The frequency is an array of counters that keeps track of how many salaries fall into respective ranges.
So i supply an array of salaries,
then my app should do the math ( salary*.9+200) is the commition paid to the sales person with a specific salary. Then it should increment the counter in the array of coutners (frequency) that keeps track of how many sales people get paid in the ranges. Then it should display the data as shown below.
Range: Frequency
$200-299 2
$300-399 3
$400-499 0
$500-599 2
$600-699 1
$700-799 5
$800-899 7
$1000 and up. 3
Than it should display the data as shown above
Yazon
10-15-2006, 07:15 PM
I've just changed the code a bit and it all seems to work, but i would like someone to look over it and see if there is anything obviously wrong with it that i shouldn't do.
Thank YOU!
public class Salary
{
public static void main(String[] args)
{
double salary[]={300, 200, 600, 700, 2000, 8000, 800, 800, 900, 6000, 1100};
int frequency []= new int [11];
System.out.printf("%10s: %6s:\n","Range", "Frequency");
for (int range = 0; range < (salary.length); range++)
{
if (10<=(int)Math.floor(((salary[range]*(.9)+200)*.01)))
++frequency[10];
else
// System.out.println((int)Math.floor(((salary[range]*(.9)+200)*.01)));
++frequency[(int)Math.floor(((salary[range]*(.9)+200)*.01))];
}
for (int range1 =2; range1<frequency.length-1; range1++)
System.out.printf("$%4d-%4d: %10d\n", range1*100,range1*100+9,frequency[range1]);
for (int range2 =11;range2<=frequency.length;range2++)
System.out.printf("$%4d %4s: %10d\n", range2*100-100,"<=", frequency[10]);
}
}
OUTPUT
Range: Frequency:
$ 200- 209: 0
$ 300- 309: 1
$ 400- 409: 1
$ 500- 509: 0
$ 600- 609: 0
$ 700- 709: 1
$ 800- 809: 1
$ 900- 909: 2
$1000 <=: 5
vBulletin® v3.8.2, Copyright ©2000-2012, Jelsoft Enterprises Ltd.