Velocity Reviews > Garbage produced

# Garbage produced

Vikram
Guest
Posts: n/a

 01-24-2011
Hello friends

the code below will find the mean (average) of some numbers, however it
produces only garbage. Can you see a problem?

Kind Regards,
Vikram

float mean(int x[])
{
int i,n;
float sum;
n=sizeof(x);
for(i=sum=0;i<n;sum+=x[i++]);
return sum/n;
}

main()
{
int* x,n;
printf("how many numbers? ");
scanf("%d",&n);
x=malloc(n*sizeof(int));
printf("enter %d numbers\n",n);
while(n--)scanf("%d",x+n);
printf("mean=%f\n",mean(x));
}

Ian Collins
Guest
Posts: n/a

 01-24-2011
On 01/25/11 09:50 AM, Vikram wrote:
> Hello friends
>
> the code below will find the mean (average) of some numbers, however it
> produces only garbage. Can you see a problem?
>
> Kind Regards,
> Vikram
>
>
> float mean(int x[])
> {
> int i,n;
> float sum;
> n=sizeof(x);

This won't do what you expect (it will give you the size of an int*),
you have to pass in the size.

--
Ian Collins

Bartc
Guest
Posts: n/a

 01-24-2011
Fred wrote:

> There is a second problem with the code not related to array vs.
> pointer.
>
> for(i=sum=0;i<n;sum+=x[i++]);
> return sum/n;
>
> The above is not a safe way to find the mean of a set of floats.
> Consider:
> x[0] = FLT_MAX;
> x[1] = FLT_MAX / 2.;
> What is the mean, and what would the above code return?

Are values near FLT_MAX really likely? If so, then it makes it pretty much
impossible to do any sort of floating point arithmetic.

A typical value of FLT_MAX is some 10**38. If values are limited to, say, a
billion billion billion (which should cover a lot of applications unless
silly units are being used), you need to add 10 billion such maximums before
you get overflow.

And that assumes you can't use double for some reason, if the numbers are
going to be big, which typically has a maximum of 10**300 or so.

Anyway, how *would* you calculate the average of lots of numbers near to
FLT_MAX?

--
Bartc

Vikram
Guest
Posts: n/a

 01-24-2011
Ian Collins writes:

> On 01/25/11 09:50 AM, Vikram wrote:
>> Hello friends
>>
>> the code below will find the mean (average) of some numbers, however it
>> produces only garbage. Can you see a problem?
>>
>> Kind Regards,
>> Vikram
>>
>>
>> float mean(int x[])

^^^^^^^

NB in this function I am considering the pointer, as an array.

>> {
>> int i,n;
>> float sum;
>> n=sizeof(x);

>
> This won't do what you expect (it will give you the size of an int*),
> you have to pass in the size.

Kind Regards,
Vikram

David Resnick
Guest
Posts: n/a

 01-24-2011
On Jan 24, 4:20*pm, Vikram <(E-Mail Removed)> wrote:
> Ian Collins writes:
> > On 01/25/11 09:50 AM, Vikram wrote:
> >> Hello friends

>
> >> the code below will find the mean (average) of some numbers, however it
> >> produces only garbage. Can you see a problem?

>
> >> Kind Regards,
> >> Vikram

>
> >> float mean(int x[])

>
> * * * * * * * ^^^^^^^
>
> NB in this function I am considering the pointer, as an array.
>
> >> {
> >> * *int i,n;
> >> * *float sum;
> >> * *n=sizeof(x);

>
> > This won't do what you expect (it will give you the size of an int*),
> > you have to pass in the size.

>

Try as an experiment doing a printf of the result of sizeof the
argument, and you will discover Ian is correct...

-David

Willem
Guest
Posts: n/a

 01-24-2011
Vikram wrote:
) the code below will find the mean (average) of some numbers, however it
) produces only garbage. Can you see a problem?
)
) float mean(int x[])
) {
) int i,n;
) float sum;
) n=sizeof(x);
) for(i=sum=0;i<n;sum+=x[i++]);
) return sum/n;
) }

That's not how arrays work in C. They don't know how big they are.
sizeof() is not meant to find out the number of elements in an array.

SaSW, Willem
--
Disclaimer: I am in no way responsible for any of the statements
made in the above text. For all I know I might be
drugged or something..
No I'm not paranoid. You all think I'm paranoid, don't you !
#EOT

Bartc
Guest
Posts: n/a

 01-24-2011
Keith Thompson wrote:
> "Bartc" <(E-Mail Removed)> writes:
>> Fred wrote:

>>> for(i=sum=0;i<n;sum+=x[i++]);
>>> return sum/n;
>>>
>>> The above is not a safe way to find the mean of a set of floats.
>>> Consider:
>>> x[0] = FLT_MAX;
>>> x[1] = FLT_MAX / 2.;
>>> What is the mean, and what would the above code return?

>>
>> Are values near FLT_MAX really likely? If so, then it makes it
>> pretty much impossible to do any sort of floating point arithmetic.

>> Anyway, how *would* you calculate the average of lots of numbers
>> near to FLT_MAX?

>
> One solution is to divide *each* number by n, them sum the quotients.

Doesn't that just move the problem elsewhere? Suppose the numbers are near
FLT_MIN?

And isn't this likely to lose accuracy (it would do with integers)?

--
Bartc

Willem
Guest
Posts: n/a

 01-24-2011
Vikram wrote:
)>> float mean(int x[])
)
) ^^^^^^^
)
) NB in this function I am considering the pointer, as an array.

You're not. You only think you are. That's not how C works.
In C, the above is exactly 100% equivalent to
float mean(int *x)

HTH, HAND.

SaSW, Willem
--
Disclaimer: I am in no way responsible for any of the statements
made in the above text. For all I know I might be
drugged or something..
No I'm not paranoid. You all think I'm paranoid, don't you !
#EOT

James Lothian
Guest
Posts: n/a

 01-24-2011
Vikram wrote:
> Ian Collins writes:
>
>> On 01/25/11 09:50 AM, Vikram wrote:
>>> Hello friends
>>>
>>> the code below will find the mean (average) of some numbers, however it
>>> produces only garbage. Can you see a problem?
>>>
>>> Kind Regards,
>>> Vikram
>>>
>>>
>>> float mean(int x[])

>
> ^^^^^^^
>
> NB in this function I am considering the pointer, as an array.

Regardless of how you like to think about it, when you pass
an array to a function in C, the function receives a pointer to
the first element of the array. That's just the way passing an array
works in C. If you take sizeof() the parameter, you'll just get the
size of the pointer, which is nothing to do with the size of the array.
There is no sensible way for the function to know the size
of the array it's been passed, unless you tell it:

float mean(int *x, int count)
{
int i;
float sum = 0.0;
for(i = 0; i < count; sum += x[i++])
;
return sum/count;
}

main()
{
int* x,n;
int count = 0;
printf("how many numbers? ");
scanf("%d",&n);
count = n;
x=malloc(n*sizeof(int));
printf("enter %d numbers\n",n);
while(n--)
scanf("%d",x+n);
printf("mean=%f\n",mean(x, count));
}

(untested code, no warranty &c)
James

Paul N
Guest
Posts: n/a

 01-24-2011
On Jan 24, 9:28*pm, Willem <(E-Mail Removed)> wrote:
> Vikram wrote:
>
> ) the code below will find the mean (average) of some numbers, however it
> ) produces only garbage. Can you see a problem?
> )
> ) float mean(int x[])
> ) {
> ) * int i,n;
> ) * float sum;
> ) * n=sizeof(x);
> ) * for(i=sum=0;i<n;sum+=x[i++]);
> ) * return sum/n;
> ) }
>
> That's not how arrays work in C. *They don't know how big they are.
> sizeof() is not meant to find out the number of elements in an array.

I beg to differ. sizeof can be used to find the number of elements in
an array. The reasons it's not working here are:

a) The x in main isn't an array, it's a pointer set using malloc;
b) Even if it was, it gets turned into a pointer when you pass it to a
function, so the x in mean is a pointer, and would be even if the x in
main was an array;
c) If x was an array of int, you would need to divide sizeof(x) by
sizeof(int) to get the number of elements.

Hope this is of use to someone.
Paul.