Velocity Reviews (http://www.velocityreviews.com/forums/index.php)
-   C Programming (http://www.velocityreviews.com/forums/f42-c-programming.html)
-   -   Garbage produced (http://www.velocityreviews.com/forums/t742519-garbage-produced.html)

 Vikram 01-24-2011 08:50 PM

Garbage produced

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 01-24-2011 08:54 PM

Re: Garbage produced

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 01-24-2011 09:10 PM

Re: Garbage produced

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 01-24-2011 09:20 PM

Re: Garbage produced

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 01-24-2011 09:25 PM

Re: Garbage produced

On Jan 24, 4:20*pm, Vikram <nos...@blank.invalid> 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 01-24-2011 09:28 PM

Re: Garbage produced

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 01-24-2011 09:48 PM

Re: Garbage produced

Keith Thompson wrote:
> "Bartc" <bc@freeuk.com> 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 01-24-2011 09:50 PM

Re: Garbage produced

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 01-24-2011 10:01 PM

Re: Garbage produced

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 01-24-2011 10:05 PM

Re: Garbage produced

On Jan 24, 9:28*pm, Willem <wil...@turtle.stack.nl> 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.

All times are GMT. The time now is 08:55 PM.