Velocity Reviews

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.

Powered by vBulletin®. Copyright ©2000 - 2014, vBulletin Solutions, Inc.
SEO by vBSEO ©2010, Crawlability, Inc.