Velocity Reviews

Velocity Reviews (http://www.velocityreviews.com/forums/index.php)
-   C Programming (http://www.velocityreviews.com/forums/f42-c-programming.html)
-   -   Re: rms from rosettacode (http://www.velocityreviews.com/forums/t807417-re-rms-from-rosettacode.html)

BartC 12-27-2011 06:14 PM

Re: rms from rosettacode
 
"superpollo" <superpollo@tznvy.pbz> wrote in message
news:4ef99d34$0$1379$4fafbaef@reader2.news.tin.it. ..
> http://rosettacode.org/wiki/Averages/Root_mean_square#C


> #include <stdio.h>
> #include <math.h>
>
> double rms(double *v)
> {
> const int n = sizeof(v) / sizeof(double);
> int i;
> double sum = 0.0;
> for (i = 0; i < n; i++)
> sum += v[i] * v[i];
> return sqrt(sum / n);
> }


> [~/superpollo]$ cc -lm rms.c && ./a.out
> nan


> what gives?


Try printing the value of n. You'll probably find it's zero. Your for-loop
while keep going for quite a while, since it starts at i=0, and won't stop
until i<0, perhaps two billion iterations later, by which time you will have
long since breached the array bounds.

(BTW size(v) is just the number of bytes in a pointer. The array size must
be made known explicity. Or you can use rand() to just guess the size; it
will probably get it right more often than your code!)

--
Bartc


Jens Thoms Toerring 12-27-2011 07:04 PM

Re: rms from rosettacode
 
superpollo <superpollo@tznvy.pbz> wrote:
> so, to summarize: it is not possible for a function that gets an array
> passed to figure by herself the size, right?


Correct. And that's because you can't pass an array to a function,
that's simply not possible in C. All you can pass to a function is
a pointer to an element (typically the first) of an array (when you
call a function with an array as an argument the array is silently
converted to such a pointer to its first element). And with just
knowing the address of the first element of the array the function
can't determine the length of the array, thus you have to pass it
separately. Or, as it already has been pointed out, you could use
a sentinel element to mark the end of the array - but that re-
quires that a value existst that never can be a valid data value
of your array.

The only real way around that would be to wrap the array into
a structure - structures (in contrast to arrays) can be passed
to functions. But, of course, there's a downside: when you pass
around a structure a complete copy of the structure must be cre-
ated which can be rather time- and memory-consuming.

Regards, Jens
--
\ Jens Thoms Toerring ___ jt@toerring.de
\__________________________ http://toerring.de

BartC 12-27-2011 07:06 PM

Re: rms from rosettacode
 


"superpollo" <superpollo@tznvy.pbz> wrote in message
news:4efa0f91$0$1375$4fafbaef@reader2.news.tin.it. ..
> BartC ha scritto:
>> "superpollo" <superpollo@tznvy.pbz> wrote in message
>> news:4ef99d34$0$1379$4fafbaef@reader2.news.tin.it. ..


>> (BTW size(v) is just the number of bytes in a pointer. The array size
>> must be made known explicity.


> so, to summarize: it is not possible for a function that gets an array
> passed to figure by herself the size, right? so the *idiomatic* way to
> give that info to the funtion should be that of the original rosettacode
> code,


That's the usual way. You might be able to invent some other way of doing
it.

Someone mentioned a 'sentinel' where some special value in the array marks
the end of the data.

Or the first element in the array is the size.

Or you pass a pointer to a struct containing an array and it's size (but the
function now takes one argument).

Etc.

Or you can just pass the array pointer, and it's length, explicitly as in
the original example; that's the simplest, when the length can be variable.

--
Bartc


James Kuyper 12-27-2011 07:11 PM

Re: rms from rosettacode
 
On 12/27/2011 01:33 PM, superpollo wrote:
> BartC ha scritto:
>> "superpollo" <superpollo@tznvy.pbz> wrote in message
>> news:4ef99d34$0$1379$4fafbaef@reader2.news.tin.it. ..
>>> http://rosettacode.org/wiki/Averages/Root_mean_square#C

>>
>>> #include <stdio.h>
>>> #include <math.h>
>>>
>>> double rms(double *v)
>>> {
>>> const int n = sizeof(v) / sizeof(double);
>>> int i;
>>> double sum = 0.0;
>>> for (i = 0; i < n; i++)
>>> sum += v[i] * v[i];
>>> return sqrt(sum / n);
>>> }

>>
>>> [~/superpollo]$ cc -lm rms.c && ./a.out
>>> nan

>>
>>> what gives?

>>
>> Try printing the value of n. You'll probably find it's zero. Your
>> for-loop while keep going for quite a while, since it starts at i=0, and
>> won't stop until i<0, perhaps two billion iterations later, by which
>> time you will have long since breached the array bounds.
>>
>> (BTW size(v) is just the number of bytes in a pointer. The array size
>> must be made known explicity. Or you can use rand() to just guess the
>> size; it will probably get it right more often than your code!)

>
> so, to summarize: it is not possible for a function that gets an array
> passed to figure by herself the size, right? so the *idiomatic* way to
> give that info to the funtion should be that of the original rosettacode
> code, or is there another way?


There's an wide variety of different ways, but all of the ones I can
think of boil down to passing to the function either a count of the
number of elements in the array, or putting a sentinel value in the
array. The wide variety comes in mainly from the many different ways you
can pass in the count, but also from freedom you have in choosing
sentinel values. Since the count and the array are closely related, I
like to package them together in a struct, making use of the flexible
array member feature introduced in C99:

struct int_vector
{
size_t n;
int array[];
}

double sum(struct int_vector* v)
{
double sum = 0.0;
for(int i = 0; i < v->n; i++
sum += v.array[i];
return sum;
}


Seebs 12-27-2011 08:13 PM

Re: rms from rosettacode
 
On 2011-12-27, superpollo <superpollo@tznvy.pbz> wrote:
> so, to summarize: it is not possible for a function that gets an array
> passed to figure by herself the size, right?


Basically, yes. To be more pedantic: You cannot pass an array to a function
in C. A function argument which looks like an array type is silently
translated into a pointer-to-array-member type. So an "int x[]" is really
just an "int *x" as a function argument.

> so the *idiomatic* way to
> give that info to the funtion should be that of the original rosettacode
> code, or is there another way?


The usual mechanism is to pass the size as a separate value, or possibly
use a sentinel. For instance, C string processing uses things which are
functionally equivalent to an array of characters, with the last member of
the array having the value 0.

-s
--
Copyright 2011, all wrongs reversed. Peter Seebach / usenet-nospam@seebs.net
http://www.seebs.net/log/ <-- lawsuits, religion, and funny pictures
http://en.wikipedia.org/wiki/Fair_Game_(Scientology) <-- get educated!
I am not speaking for my employer, although they do rent some of my opinions.

Ben Pfaff 12-27-2011 10:57 PM

Re: rms from rosettacode
 
jt@toerring.de (Jens Thoms Toerring) writes:

> Correct. And that's because you can't pass an array to a function,
> that's simply not possible in C. All you can pass to a function is
> a pointer to an element (typically the first) of an array (when you
> call a function with an array as an argument the array is silently
> converted to such a pointer to its first element). [...]


C99 didn't change any of these fundamentals, but it did make
passing multidimensional arrays to functions more convenient
using "variably modified parameters", which seem to be related to
this topic even if not an answer to the OP's question.

Here's the example from the standard itself:

void addscalar(int n, int m, double a[n][n*m+300], double x);

int main()
{
double b[4][308];
addscalar(4, 2, b, 2.17);
return 0;
}

void addscalar(int n, int m, double a[n][n*m+300], double x)
{
for (int i = 0; i < n; i++)
for (int j = 0, k = n*m+300; j < k; j++)
// a is a pointer to a VLA with n*m+300 elements
a[i][j] += x;
}

--
"I should killfile you where you stand, worthless human." --Kaz

Johann Klammer 12-27-2011 11:13 PM

Re: rms from rosettacode
 
superpollo wrote:
> so, to summarize: it is not possible for a function that gets an array
> passed to figure by herself the size, right? so the *idiomatic* way to
> give that info to the funtion should be that of the original rosettacode
> code, or is there another way?
>

You *could* use a #define to hide away the size argument.

double rms(double *v, int n);

#define RMS(THIS_MUST_BE_A_VECTOR) \
rms(THIS_MUST_BE_A_VECTOR,sizeof(THIS_MUST_BE_A_VE CTOR)/sizeof(double))

but this will do the wrong thing when you pass a double *
So it is a bit questionable.

Johann Klammer 12-27-2011 11:23 PM

Re: rms from rosettacode
 
superpollo wrote:
....
> so, to summarize: it is not possible for a function that gets an array
> passed to figure by herself the size, right? so the *idiomatic* way to
> give that info to the funtion should be that of the original rosettacode
> code, or is there another way?

....

You *could* use a #define to hide away the size argument.

double rms(double *v, int n);

#define RMS(THIS_MUST_BE_A_VECTOR)
rms(THIS_MUST_BE_A_VECTOR,sizeof(THIS_MUST_BE_A_VE CTOR)/sizeof(double))

but this will do the wrong thing when you pass a double *
So it is a bit questionable.

88888 Dihedral 12-27-2011 11:54 PM

Re: rms from rosettacode
 
superpollo於 2011年12月28日星期三UTC+8上午2時33分51 寫道:
> BartC ha scritto:
> > "superpollo" <superpollo@tznvy.pbz> wrote in message
> > news:4ef99d34$0$1379$4fafbaef@reader2.news.tin.it. ..
> >> http://rosettacode.org/wiki/Averages/Root_mean_square#C

> >
> >> #include <stdio.h>
> >> #include <math.h>
> >>
> >> double rms(double *v)
> >> {
> >> const int n = sizeof(v) / sizeof(double);
> >> int i;
> >> double sum = 0.0;
> >> for (i = 0; i < n; i++)
> >> sum += v[i] * v[i];
> >> return sqrt(sum / n);
> >> }

> >
> >> [~/superpollo]$ cc -lm rms.c && ./a.out
> >> nan

> >
> >> what gives?

> >
> > Try printing the value of n. You'll probably find it's zero. Your
> > for-loop while keep going for quite a while, since it starts at i=0, and
> > won't stop until i<0, perhaps two billion iterations later, by which
> > time you will have long since breached the array bounds.
> >
> > (BTW size(v) is just the number of bytes in a pointer. The array size
> > must be made known explicity. Or you can use rand() to just guess the
> > size; it will probably get it right more often than your code!)

>
> so, to summarize: it is not possible for a function that gets an array
> passed to figure by herself the size, right? so the *idiomatic* way to
> give that info to the funtion should be that of the original rosettacode
> code, or is there another way?
>
> bye
>
> --
> Chissa' perche' in un triangolo (5*5)/2=12.5
> ci stanno 125 triangolini ???


This does matter in the pass by register implementations of calling
a function. The rule of thumb in IA32 X86 is that 3 32bit parameters
to be the input parameters of a function is OK by __fastcall.


But for MIPS compatible CPUs, things are not the same.


Seebs 12-28-2011 06:29 AM

Re: rms from rosettacode
 
On 2011-12-28, Keith Thompson <kst-u@mib.org> wrote:
> None of that has anything at all to do with the statement to which
> you're responding.


I am not sure this is true, because I do not think we have compelling
evidence that the poster in question is responding to posted statements,
even if sometimes those statements are quoted.

Honestly, the more I read this, the more it looks like word salad.

-s
--
Copyright 2011, all wrongs reversed. Peter Seebach / usenet-nospam@seebs.net
http://www.seebs.net/log/ <-- lawsuits, religion, and funny pictures
http://en.wikipedia.org/wiki/Fair_Game_(Scientology) <-- get educated!
I am not speaking for my employer, although they do rent some of my opinions.


All times are GMT. The time now is 11:16 AM.

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