Re: rms from rosettacode

Discussion in 'C Programming' started by James Kuyper, Dec 27, 2011.

  1. James Kuyper

    James Kuyper Guest

    On 12/27/2011 05:25 AM, superpollo wrote:
    > http://rosettacode.org/wiki/Averages/Root_mean_square#C
    >
    >
    > ...
    > [~/superpollo]$ cat rms_rc.c
    > #include <stdio.h>
    > #include <math.h>
    >
    > double rms(double *v, int n)
    > {
    > int i;
    > double sum = 0.0;
    > for (i = 0; i < n; i++)
    > sum += v * v;
    > return sqrt(sum / n);
    > }
    >
    > int main()
    > {
    > double v[] = { 1., 2., 3., 4., 5., 6., 7., 8., 9., 10. };
    > printf("%f\n", rms(v, sizeof(v) / sizeof(double)));
    >
    > return 0;
    > }
    > [~/superpollo]$ cc -lm rms_rc.c && ./a.out
    > 6.204837
    > ...
    >
    > that works fine, but i am quite unhappy with having to say to the rms
    > function how big the array is... after all, i guess, shouldn't the
    > function be able to figure it out herself?


    How? The method you use below doesn't work. The only alternative I can
    think of to passing in the length of the array is to put a sentinel
    value at the end of the array like the null character at the end of a
    string. For floating point values, nan() is a reasonable value to use,
    in which case you can test for the end of the array using isnan(v).

    > ... to i tried:
    >
    > ...
    > [~/superpollo]$ cat rms.c
    > #include <stdio.h>
    > #include <math.h>
    >
    > double rms(double *v)
    > {
    > const int n = sizeof(v) / sizeof(double);


    v is pointer to double. sizeof(v) is therefore the same as
    sizeof(double*). 'n' is therefore a fixed value:
    sizeof(double*)/sizeof(double). It's value has nothing to do with how
    long the array whose first member 'v' points at. On many systems, it
    will have a value of 0.

    > int i;
    > double sum = 0.0;
    > for (i = 0; i < n; i++)
    > sum += v * v;
    > return sqrt(sum / n);


    If 'n' does have a value of zero, that division means that your program
    has undefined behavior. Whether or not 'n' is 0 can be determined at
    compile time, so a sufficiently smart compiler could even refuse to
    compile your code.
    --
    James Kuyper
    James Kuyper, Dec 27, 2011
    #1
    1. Advertising

  2. James Kuyper

    James Kuyper Guest

    On 12/27/2011 07:01 AM, superpollo wrote:
    > James Kuyper ha scritto:
    >> On 12/27/2011 05:25 AM, superpollo wrote:
    >>> http://rosettacode.org/wiki/Averages/Root_mean_square#C
    >>>
    >>>
    >>> ...
    >>> [~/superpollo]$ cat rms_rc.c
    >>> #include <stdio.h>
    >>> #include <math.h>
    >>>
    >>> double rms(double *v, int n)
    >>> {
    >>> int i;
    >>> double sum = 0.0;
    >>> for (i = 0; i < n; i++)
    >>> sum += v * v;
    >>> return sqrt(sum / n);
    >>> }
    >>>
    >>> int main()
    >>> {
    >>> double v[] = { 1., 2., 3., 4., 5., 6., 7., 8., 9., 10. };
    >>> printf("%f\n", rms(v, sizeof(v) / sizeof(double)));
    >>>
    >>> return 0;
    >>> }
    >>> [~/superpollo]$ cc -lm rms_rc.c && ./a.out
    >>> 6.204837
    >>> ...
    >>>
    >>> that works fine, but i am quite unhappy with having to say to the rms
    >>> function how big the array is... after all, i guess, shouldn't the
    >>> function be able to figure it out herself?

    >>
    >> How?

    >
    > just in the same way as "main" does. no?


    main() doesn't figure out the length itself; it's told the length by the
    routine that calls main, by two different mechanisms: argc contains the
    count of the arguments; since you're objecting to having to pass 'n' to
    rms(), you should object, on the same ground, to the fact that the
    implementation has to pass argc to main(). main() also uses the sentinel
    value method I mentioned in the part of my message which you snipped:
    argv[argc] is required to be a null pointer.
    --
    James Kuyper
    James Kuyper, Dec 27, 2011
    #2
    1. Advertising

  3. James Kuyper

    James Kuyper Guest

    On 12/27/2011 07:36 AM, superpollo wrote:
    > James Kuyper ha scritto:
    >> On 12/27/2011 07:01 AM, superpollo wrote:
    >>> James Kuyper ha scritto:
    >>>> On 12/27/2011 05:25 AM, superpollo wrote:
    >>>>> http://rosettacode.org/wiki/Averages/Root_mean_square#C
    >>>>>
    >>>>>
    >>>>> ...
    >>>>> [~/superpollo]$ cat rms_rc.c
    >>>>> #include <stdio.h>
    >>>>> #include <math.h>
    >>>>>
    >>>>> double rms(double *v, int n)
    >>>>> {
    >>>>> int i;
    >>>>> double sum = 0.0;
    >>>>> for (i = 0; i < n; i++)
    >>>>> sum += v * v;
    >>>>> return sqrt(sum / n);
    >>>>> }
    >>>>>
    >>>>> int main()
    >>>>> {
    >>>>> double v[] = { 1., 2., 3., 4., 5., 6., 7., 8., 9., 10. };
    >>>>> printf("%f\n", rms(v, sizeof(v) / sizeof(double)));
    >>>>>
    >>>>> return 0;
    >>>>> }
    >>>>> [~/superpollo]$ cc -lm rms_rc.c && ./a.out
    >>>>> 6.204837
    >>>>> ...
    >>>>>
    >>>>> that works fine, but i am quite unhappy with having to say to the rms
    >>>>> function how big the array is... after all, i guess, shouldn't the
    >>>>> function be able to figure it out herself?
    >>>> How?
    >>> just in the same way as "main" does. no?

    >>
    >> main() doesn't figure out the length itself; it's told the length by the
    >> routine that calls main, by two different mechanisms: argc contains the
    >> count of the arguments; since you're objecting to having to pass 'n' to
    >> rms(), you should object, on the same ground, to the fact that the
    >> implementation has to pass argc to main(). main() also uses the sentinel
    >> value method I mentioned in the part of my message which you snipped:
    >> argv[argc] is required to be a null pointer.

    >
    > i really cannot se how the "main()" arguments are related to the
    > question, since "v[]" is declared INSIDE "main()".


    I assumed that you were comparing the 'v' argument of rms() to the argv
    argument often (but not necessarily) passed to main(). That would be a
    valid comparison, and argument 'n' of rms() corresponds to the argc
    argument of main(). I didn't realize that you're referring to the 'v'
    defined inside of main(), because that v is irrelevant to your original
    question - the fact that you think it's relevant is a symptom of your
    misunderstanding of what's going on in this program.

    The 'v' identifier in main() has block scope - it can only be referred
    to inside the body of main(). The 'v' identifier in rms() has block
    scope too; it can only be referred to in the parameter list or body of
    rms(). Despite the fact that they have the same name, they identify
    different objects, of different types. The 'v' in main() identifies an
    array of 10 doubles. The 'v' in rms() identifies a pointer to double. I
    general, those will have two very different sizes.

    > on a related note: how can "sizeof" figure out the size of "v[]"?


    When you use sizeof(v) inside of main, it gives you the size of the
    array of 10 doubles named v. The compiler knows how big a double is, and
    it knows that v[] contains 10 of them, so sizeof(v) just gives
    10*sizeof(double), on many implementations, sizeof(double) is 8 - on
    such implementations, sizeof(v) in main() would therefore be 80.

    When you use sizeof(v) inside of rms, it will give you the size of the
    pointer to double named 'v'. On many implementations, pointers are
    generally 32-bit, and bytes are 8 bit, in which case sizeof(v) in rms()
    would be 4.

    > is
    > there some sentinel implicitly at the end? if yes, why not passing it
    > around to "rms()", so ther the finction can figure out the size herself?
    > it does not seem to create such a big overhead, for instance.


    The C language leaves such details under your control; "sizeof
    expression" only gives you the size of the object referred to by the
    expression; if that object is a pointer to the first element of an
    array, that will be the size of the pointer; in general, it won't be the
    size of the array, and in the unlikely event that it is also the size of
    the array, that's just a coincidence.


    In a part of my message that you chose not to quote, I talked about n
    having a value of sizeof(v)/sizeof(double), which corresponds to
    sizeof(double*)/sizeof(double), an expression that has a value of 0 on
    many systems. I must not have been fully awake yet when I wrote that.
    sizeof(v) gives sizeof(double*) only in rms(); the only place where your
    code divides sizeof() values is in main(). Please ignore that part of my
    comments.
    James Kuyper, Dec 27, 2011
    #3
  4. James Kuyper <> writes:
    [...]
    > How? The method you use below doesn't work. The only alternative I can
    > think of to passing in the length of the array is to put a sentinel
    > value at the end of the array like the null character at the end of a
    > string. For floating point values, nan() is a reasonable value to use,
    > in which case you can test for the end of the array using isnan(v).

    [...]

    Implementations aren't required to support NaNs.

    --
    Keith Thompson (The_Other_Keith) <http://www.ghoti.net/~kst>
    Will write code for food.
    "We must do something. This is something. Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"
    Keith Thompson, Dec 27, 2011
    #4
  5. James Kuyper

    James Kuyper Guest

    On 12/27/2011 05:42 PM, Keith Thompson wrote:
    > James Kuyper <> writes:
    > [...]
    >> How? The method you use below doesn't work. The only alternative I can
    >> think of to passing in the length of the array is to put a sentinel
    >> value at the end of the array like the null character at the end of a
    >> string. For floating point values, nan() is a reasonable value to use,
    >> in which case you can test for the end of the array using isnan(v).

    > [...]
    >
    > Implementations aren't required to support NaNs.


    True; my statement applies only to those that do.

    In my own work, we can't assume support for NaNs, or even for C99
    itself. We use different values in different contexts; for instance, we
    use -999.0 as a fill value for floating point values representing angles
    in the range -180.0 <= theta < 180.0.
    James Kuyper, Dec 27, 2011
    #5
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Rohit

    j2me and RMS

    Rohit, Apr 2, 2004, in forum: Java
    Replies:
    1
    Views:
    956
    Darryl L. Pierce
    Apr 2, 2004
  2. leggolas

    RMS and midlets

    leggolas, Mar 14, 2005, in forum: Java
    Replies:
    4
    Views:
    1,121
    leggolas
    Mar 22, 2005
  3. Spacey Spade
    Replies:
    4
    Views:
    621
    Remon van Vliet
    Jun 15, 2005
  4. BartC

    Re: rms from rosettacode

    BartC, Dec 27, 2011, in forum: C Programming
    Replies:
    11
    Views:
    447
    88888 Dihedral
    Dec 28, 2011
  5. Kaz Kylheku

    Re: rms from rosettacode

    Kaz Kylheku, Dec 27, 2011, in forum: C Programming
    Replies:
    13
    Views:
    470
    Nick Keighley
    Dec 29, 2011
Loading...

Share This Page