Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

findAverage ()

0 views
Skip to first unread message

Michael

unread,
Jan 21, 2006, 6:02:55 PM1/21/06
to
Hello, good day all. I had a question about getting an average value from an
array[]. I have the following piece of code below, for reference.

void findAverage(){
for(int i = 0; i<scores.length-1;i++){
sum += scores[i];
count++;
}


if(count>0){
average = (double)sum /(double) count;
System.out.println(average);
}else{
average=0;
}
}

Okay, I have figured that the problem lies within the sum variable. Since
the application only seems to be giving the average number of the last value
in the array. How do I allow for the suming of values in different elements
within the array. That is how do I add the values within the array to yield
the sum, and assign those summed values to the sum variable. My counter is
working fine, only the sum variable is not summing all of the requested
values. I see sum+=scores[i]; as the following sum= scores[0] + scores[1];
Please correct me if I am using the += operator incorrectly. Thanks again.


Allan Bruce

unread,
Jan 21, 2006, 6:33:28 PM1/21/06
to

"Michael" <mbia...@shaw.ca> wrote in message
news:z4zAf.192472$tl.39342@pd7tw3no...

Where do you get your variables from? Here is a method that will return the
average given an array of doubles.
Allan

public double findAverage(double [] array)
{
double sum = 0.0;
for (int i=0; i<array.length; i++)
sum += array[i];

if (array.length == 0)
return 0.0;
else
return (sum/array.length);
}


Daniel Dyer

unread,
Jan 21, 2006, 6:42:34 PM1/21/06
to
On Sat, 21 Jan 2006 23:02:55 -0000, Michael <mbia...@shaw.ca> wrote:

> Hello, good day all. I had a question about getting an average value
> from an
> array[]. I have the following piece of code below, for reference.
>
> void findAverage(){
> for(int i = 0; i<scores.length-1;i++){
> sum += scores[i];
> count++;
> }

This loop will miss out the last value in the array. Either lose the -1
or change the operator to <=.

> if(count>0){
> average = (double)sum /(double) count;
> System.out.println(average);
> }else{
> average=0;
> }
> }

Where are your variables (sum, average and count) declared? Are they
instance variables (declared outside of the findAverage method)? They
should probably be local variables (unless you have explicitly been told
to do it this way for the assignment). With your approach, if you call
findAverage more than once, the sum is never reset to zero.

> Okay, I have figured that the problem lies within the sum variable. Since
> the application only seems to be giving the average number of the last
> value
> in the array.

That code doesn't even look at the last value of the array. Are you sure
your diagnosis is correct?

> How do I allow for the suming of values in different elements
> within the array. That is how do I add the values within the array to
> yield
> the sum, and assign those summed values to the sum variable. My counter
> is
> working fine, only the sum variable is not summing all of the requested
> values.

It should work OK, except for the issues I mentioned. Your use of +=
seems to be correct.

Dan.

--
Daniel Dyer
http://www.dandyer.co.uk

Michael Redlich

unread,
Jan 21, 2006, 7:08:16 PM1/21/06
to

Hi Michael:

I see a couple of minor things here.

(a) In your for loop, you aren't getting the last value of your array.
This is because you subtracted 1 from scores.length which only reaches
element n - 2. Iterating from 0 to n -1 elements is accomplished with
the '<' conditional that you used. I would also recommend that you
take the scores.length variable out of the for loop because it gets
computed n times. I would therefore change your for loop to:

int n = scores.length;
for(int i = 0; i < n; ++i)
{
//
}

(b) using a count variable is redundant since you already have
scores.length.

(c) I don't see sum being initialized to zero anywhere. Are scores and
sum global variables? I assume that the elements in the scores array
and sum are integers since you cast them in the average calculation.

(d) You are using the += operator properly.

(e) Why not return a double type as opposed to void in your method? I
would also pass in your scores array as a parameter. Your method can
be changed to:

public double findAverage(int[] scores)
{
int n = scores.length;
int sum = 0;
for(int i = 0; i < n; ++i) // also note the use of prefix increment
- it's more efficient...
sum += scores[i];
if(n > 0)
return (double)sum / (double) n;
return 0.0;
}

Hope this helps...

Sincerely,

Mike.

--- ACGNJ Java Users Group (http://www.javasig.org/)

Daniel Dyer

unread,
Jan 21, 2006, 7:23:43 PM1/21/06
to
On Sun, 22 Jan 2006 00:08:16 -0000, Michael Redlich <mi...@redlich.net>
wrote:

> I would also recommend that you
> take the scores.length variable out of the for loop because it gets
> computed n times. I would therefore change your for loop to:
>
> int n = scores.length;
> for(int i = 0; i < n; ++i)
> {
> //
> }

Is there any performance improvement at all there? The length is not
computed, it's already known, so it's a direct access to a final field.

Eric Jacoboni

unread,
Jan 21, 2006, 7:28:10 PM1/21/06
to
"Michael Redlich" <mi...@redlich.net> writes:

> int n = scores.length;
> for(int i = 0; i < n; ++i)
> {
> //
> }

You may even go further with a constant...

final int N = scores.length;
for (.....) { .... }

--
Eric Jacoboni, ne il y a 1441330013 secondes

Daniel Dyer

unread,
Jan 21, 2006, 7:54:47 PM1/21/06
to
On Sun, 22 Jan 2006 00:28:10 -0000, Eric Jacoboni <ja...@neottia.net> wrote:

> "Michael Redlich" <mi...@redlich.net> writes:
>
>> int n = scores.length;
>> for(int i = 0; i < n; ++i)
>> {
>> //
>> }
>
> You may even go further with a constant...
>
> final int N = scores.length;
> for (.....) { .... }

Just tried the three approaches for a loop that summed the elements of a
100 million element array (all elements set to zero). Tried both client
and server VMs:

Client Server

Direct access to array.length: 380ms 246ms
Non-final local variable: 305ms 245ms
Final local variable: 302ms 245ms

(Sun Java 1.5.0_06 under Linux on a 2.53Ghz P4).

So you might get a tiny advantage on the client VM (75 milliseconds, or
less than a billionth of a second per access) compared to directly
accessing the length, it's not significant even in this most trivial of
loops with an astronomical number of iterations. The server VM is clever
enough to optimise the field access.

Making the local variable final has no effect on performance.

These kind of optimisations should be left to the compiler/VM.

Ian Mills

unread,
Jan 21, 2006, 7:52:22 PM1/21/06
to
sum += scores[i] is equivalent to sum = sum + scores[i].
how are you populating your array and what are the results you are getting

"Michael" <mbia...@shaw.ca> wrote in message
news:z4zAf.192472$tl.39342@pd7tw3no...

Michael Redlich

unread,
Jan 21, 2006, 8:19:53 PM1/21/06
to

Daniel Dyer wrote:

> Is there any performance improvement at all there? The length is not
> computed, it's already known, so it's a direct access to a final field.
>

Hi Dan:

Good point. You're right, using the length field property shouldn't be
a major concern with regards to performance. I'm just so used to that
practice, especially when it involves a call to a method to get the
number of elements, e.g, scores.size(), like some of the Java
Collections have.

Thanks for pointing that out.

Hal Rosser

unread,
Jan 21, 2006, 8:35:07 PM1/21/06
to

"Michael" <mbia...@shaw.ca> wrote in message
news:z4zAf.192472$tl.39342@pd7tw3no...

Try initializing sum and count to zero at the top of the method.
-- or just divide by scores.length instead of counting something you already
know.
and can we assume the variables you are using were appropriately scoped?


Andrew McDonagh

unread,
Jan 22, 2006, 3:51:26 AM1/22/06
to
Daniel Dyer wrote:

snipped a brilliant example


>
> Making the local variable final has no effect on performance.
>
> These kind of optimisations should be left to the compiler/VM.
>
> Dan.
>


Thank Daniel for this - the sooner people stop guessing and use a
test/profiler to find where the real bottle necks are...the better!

Michael

unread,
Jan 22, 2006, 4:21:04 AM1/22/06
to
Thanks guys for the information; it is greatly appreciated. Basically I am
writing a worker class which has other methods() aswell. Then I am writing
an application class to instantiate this new object to test its methods. I
am implementing the Comparable interface from within the class which
contains the findAverage(). This class also uses a fillStudent() method that
is implemented using the StringTokenizer object. Also there is a
getName(),getAverage() ( both of which just return either a String name, or
a average which is of type double. And finally the compareTo(Obj) method.
And finally the toString() method to return all information from object.My
constructor for this class is initializing a array called scores to 5
slots.Also average is set to 0.0, and name is initilized to ""( an empty
string). When I run my application class I get the following.

Student's Name: mike

The average of the test mark scores is 1.8

The average should be 9.75 from the values of 10.0 10.0 9.5 9.5. So I am
still doing something wrong.

"Hal Rosser" <hmro...@bellsouth.net> wrote in message
news:GgBAf.9104$TK2....@bignews1.bellsouth.net...

Michael

unread,
Jan 22, 2006, 4:23:38 AM1/22/06
to
Here is my method edited.

void findAverage(){
int sum = 0;
int n = scores.length;
for(int i = 0; i<n;i++){
sum += scores[i];
}
if(n > 0){
average = (double)sum /(double) n;
}else{
average=0;


}
}
"Michael" <mbia...@shaw.ca> wrote in message

news:48IAf.305111$2k.229230@pd7tw1no...

Andrew McDonagh

unread,
Jan 22, 2006, 4:53:59 AM1/22/06
to
Michael wrote:
> Here is my method edited.
>
> void findAverage(){
> int sum = 0;
> int n = scores.length;
> for(int i = 0; i<n;i++){
> sum += scores[i];
> }
> if(n > 0){
> average = (double)sum /(double) n;
> }else{
> average=0;
> }
> }

A small but important point...


using letters for variable names is not a good habit to get into..

The case of 'n' above is a good example.

'n' is really the length of the scores array, so a good name for it
could be... numberOfScores, etc...

using meaningful names saves the readers (thats you, your colleagues,
us, others) from having to remember or mentally compile the code to
figure out what 'n' is.


Aside from that a different way to write the method....


public void findAverage(){
if (scores.length = 0) {
average = 0;
return;
}


int sum = 0;

for(int i = 0; i < scores.length;i++){
sum += scores[i];
}

average = (double)sum /(double) scores.length;
}


The first if test tells the read very clearly that if there is no
scores, then average is zero and theres nothing left to do, so return.

Its not there for any performance optimisation...its there for clarity.

HTH

Andrew

Michael

unread,
Jan 22, 2006, 5:04:46 AM1/22/06
to
I think my findAverage() might indeed be working but, my fillStudent() is
where the problem maybe lies. I just edited some code now I get a compile
error. The error is the following.

Exception in thread "main" java.util.NoSuchElementException

at java.util.StringTokenizer.nextToken(StringTokenizer.java:332)

at Student.fillStudent(Student.java:32)

at StudentApp.main(StudentApp.java:27)

void fillStudent(String s){
StringTokenizer t = new StringTokenizer(s);
name = t.nextToken();

for(int i=0; i<scores.length;i++){
scores[i] += Double.parseDouble(t.nextToken());
}
}

I am somewhat confused on The StringTokenizer class. I know that since I
want to read in a name(which is a string), and then following this name will
be 4 test scores(real marks) I have to account for both strings and double.
That is way I am creating a new StringTokenizer object to hold all of these
values. Well I can just call t.nextToken() to get the next segment of the
string. I go this for name. But then to get a double value I extract the
token then try to parse that into a double. But for some reason, that aspect
of my code I don't think is working properly. Any suggestions, thanks again.

"Andrew McDonagh" <ne...@andrewcdonagh.f2s.com> wrote in message
news:dqvknq$ucg$1...@news.freedom2surf.net...

Ian Mills

unread,
Jan 22, 2006, 7:33:27 AM1/22/06
to
This is a runtime error caused by the fact that your tokenizer has run
out of elements. Try modifying your code as follows:

int i=0;
while(t.hasMoreTokens())
{ scores[i]+=Double.parseDouble(t.nextToken());
i++
}

This should cure the problem

opalpa@gmail.com opalinski from opalpaweb

unread,
Jan 22, 2006, 9:38:35 AM1/22/06
to
Your code is broken down akwardly. Folks have suggested that you make
a function that takes as parameter numbers to be averaged and returns
an average. Similarly make a function that returns numbers after
reading them in. Having scores be a member variable and average be a
member variable is poor practice.

I think you're just learning (this is homework, right?).

You're creating scores variable somewhere else from where you are
reading it. How do you know that the scores array will not have too
many entries or too few entries for what you are reading? Extra zeros
at the end are going effect the average calculation.

Here is a tip: display the values contained in scores, see if they are
correct.

Opalinski
opa...@gmail.com
http://www.geocities.com/opalpaweb/

Michael

unread,
Jan 23, 2006, 1:56:47 AM1/23/06
to
Thanks guys for all the input. I think I figured it almost all out. However
I have been trying to convert to one decimal place. I believe once I can
round my average variable up; it should then be right on the money. I have
been looking at DecimalFormat class; but unsure how to use its methods in my
class. Hehe I'll play around with it. Thanks again. :)
<opa...@gmail.com> wrote in message
news:1137940715.6...@g47g2000cwa.googlegroups.com...

Ian Mills

unread,
Jan 23, 2006, 3:18:38 PM1/23/06
to
Michael wrote:

You may also want to look at BigDecimal instead of double as yhis allows
you to specify the decimals and also the rounding method.

Michael

unread,
Jan 23, 2006, 8:14:05 PM1/23/06
to
Hello thanks again. I have tried to implement BigDecimal objects into my
code. However now I get a worst outcome, then without the BigDecimal object
instantiated.
Before I entered.
mike 10 10 9.5 9.5
and got the following
Student's Name: mike

The average of the test mark scores is 9.5

now with BigDecimal object used I get

Student's Name: mike

The average of the test mark scores is 8

I get a worst result. How do you specify to want decimal place you want and
rounding method.

snippet;

void findAverage(){
int sum = 0;

for(int i = 0; i < scores.length;i++){
sum += scores[i];
}


if(scores.length > 0){
//average = (double)sum /(double) numberOfScores;
BigDecimal exactSum = new BigDecimal(sum);
System.out.println(sum);
System.out.println(exactSum);
BigDecimal exactNumber=new BigDecimal(scores.length);
BigDecimal exactAverage= exactSum.divide(exactNumber);
avg=exactAverage;
}else{
average = 0;
}

}

Thanks again.

cheers!

"Ian Mills" <ne...@siteone.free-online.co.uk> wrote in message
news:43d53a21$0$2685$ed26...@ptn-nntp-reader02.plus.net...

Ian Mills

unread,
Jan 24, 2006, 3:31:26 PM1/24/06
to
Michael wrote:

It's all in the javadoc for BigDecimaland much mor besides) but
basically you define the scale and rounding method required when calling
the divide method.

e.g exactSum.divide(exactNumber,2,BigDecimal.ROUND_HALF_UP) would give
you an answer to 4 decimals rounding normally (<5 rounds down >= 5
rounds up)

opalpa@gmail.com opalinski from opalpaweb

unread,
Jan 24, 2006, 4:03:15 PM1/24/06
to
FYI: In one branch of your if you assign to "avg" -- three letters. In
second branch of your if you assign to "average"-more letters. avg and
average are different names and, assuming the above code compiled for
you, different types.


All the best Mike. Maybe, in the future, you'll come back to this
thread and notice advice which would have prevented this mistake.

Cheers. Enjoy exploring programming

Opalinski
opa...@gmail.com
http://www.geocities.com/opalpaweb/

opalpa@gmail.com opalinski from opalpaweb

unread,
Jan 24, 2006, 4:05:07 PM1/24/06
to
btw, in the line that prints the average, are you using the correct
variable? I mean do you decide between avg and average?

Opalinski
opa...@gmail.com
http://www.geocities.com/opalpaweb/

Michael

unread,
Jan 24, 2006, 9:05:51 PM1/24/06
to
Thanks guys; it is much apreciated. I finally got it to work right using
DecimalFormat Class. I ued average instead of avg. Thanks for pointing that
out. ttyl
<opa...@gmail.com> wrote in message
news:1138136707....@z14g2000cwz.googlegroups.com...
0 new messages