Need HELP

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • kupiko

    Need HELP

    Please can anyone help me on this code? I want
    to write all odd numbers in range from a to b but it doesn't work at all
    cases mainly when a is higher than b and when i type in negative numbers.


    Here is the code and i would appreciate anybody helping me. THANKS.

    #include<stdio. h>
    #include<math.h >
    void odd(float x, float y);
    void change(float x, float y);

    void odd(float x, float y)
    {
    int i;
    if (x>y) change(x,y);
    x=roundf(x);
    y=roundf(y);
    for(i=1;i<(y-x)+1;i++)
    if ( fmodf ((x+i),2)==1 || fmodf ((x+i),2)==-1 ) printf( "%f
    ",(x+i) );
    }

    void change(float x, float y)
    {
    float c;
    c=x;
    x=y;
    y=c;
    }

    main()
    {

    float a,b;
    printf("Type two real numbers :");
    scanf("%f%f",&a ,&b);
    odd(a,b);
    getchar();
    getchar();
    }

  • Don Morris

    #2
    Re: Need HELP

    kupiko wrote:[color=blue]
    > Please can anyone help me on this code? I want
    > to write all odd numbers in range from a to b but it doesn't work at all
    > cases mainly when a is higher than b and when i type in negative numbers.
    >
    >
    > Here is the code and i would appreciate anybody helping me. THANKS.
    >
    > #include<stdio. h>
    > #include<math.h >
    > void odd(float x, float y);
    > void change(float x, float y);
    >
    > void odd(float x, float y)
    > {
    > int i;
    > if (x>y) change(x,y);
    > x=roundf(x);
    > y=roundf(y);
    > for(i=1;i<(y-x)+1;i++)
    > if ( fmodf ((x+i),2)==1 || fmodf ((x+i),2)==-1 ) printf( "%f
    > ",(x+i) );
    > }
    >
    > void change(float x, float y)
    > {
    > float c;
    > c=x;
    > x=y;
    > y=c;
    > }[/color]

    Just on first glance (i.e. I wouldn't swear that you don't have
    other bugs...), your problem is in how you call change().
    When you call a C function, the function works on local copies
    of the parameters -- not on the values in the scope of the caller.

    So here -- you have the following:

    main gets a and b (main:a, main:b for short), calls odd with them.
    odd gets copies of main:a, main:b which are named odd:x, odd:y.
    main:a and main:b are (of course) unchanged).

    odd calls change with odd:x, odd:y -- and change's copies are
    called change:x, change:y.

    change:x, change:y and change:c are modified and change returns..
    leaving odd:x and odd:y unchanged.

    So if you want to do this, I'd recommend one of the following:

    i) Rewrite change to be a macro, not a function so that
    you work with the actual variables you intend, such as:

    #define SWAP_FLOAT(floa t __x, float __y ) \
    do { \
    float __temp; \
    __temp = __x; \
    __x = __y; \
    __y = __temp; \
    } while (0)

    This lets you use SWAP_FLOAT as if it were a function,
    having odd() do SWAP_FLOAT(x, y) will change the
    variables in odd()'s scope [odd:x, odd:y] as you intend.

    ii) Rewrite change to work with the addresses of the
    variables, not the contents.

    void change (float *x, float *y)
    {
    float temp;
    if ( x == NULL || y == NULL ) {
    /* Die with error? Your call on handling */
    return;
    }
    temp = *x;
    *x = *y;
    *y = temp;
    }

    Don
    [color=blue]
    >
    > main()
    > {
    >
    > float a,b;
    > printf("Type two real numbers :");
    > scanf("%f%f",&a ,&b);
    > odd(a,b);
    > getchar();
    > getchar();
    > }
    >[/color]

    Comment

    • kupiko

      #3
      Re: Need HELP

      >void change (float *x, float *y)[color=blue]
      >{
      > float temp;
      > if ( x == NULL || y == NULL ) {
      > /* Die with error? Your call on >handling */
      > return;
      > }
      > temp = *x;
      > *x = *y;
      > *y = temp;
      >}[/color]

      Thank you very much for this advice. It's first time I see how to use
      pointers and it is useful as I see but still there are errors in my
      rewritten code. And i don't know anything about pointers so i can't solve
      what it mean could you please help me?
      I haven't much time otherwise i would not annoy you.

      ERROR:
      cannot convert `float' to `float*' for argument `1' to `void
      vymen(float*, float*)'

      CODE:

      #include<stdio. h>
      #include<math.h >

      void odd(float x, float y);
      void change(float *x, float *y);

      void odd(float x, float y)
      {
      int i;
      if (x>y) change(x,y);
      x=roundf(x);
      y=roundf(y);
      for(i=1;i<(y-x)+1;i++)
      if ( fmodf ((x+i),2)==1 || fmodf ((x+i),2)==-1 ) printf( "%f
      ",(x+i) );
      }

      void change(float *x, float *y)
      {
      float c;
      if ( x==NULL || y==NULL ) return;
      c=*x;
      *x=*y;
      *y=c;
      }

      main()
      {
      float a,b;
      printf("Type two real numbers :");
      scanf("%f%f",&a ,&b);
      odd(a,b);
      getchar();
      getchar();
      }


      Comment

      • Don Morris

        #4
        Re: Need HELP

        kupiko wrote:[color=blue][color=green]
        >>void change (float *x, float *y)
        >>{
        >> float temp;
        >> if ( x == NULL || y == NULL ) {
        >> /* Die with error? Your call on >handling */
        >> return;
        >> }
        >> temp = *x;
        >> *x = *y;
        >> *y = temp;
        >>}[/color]
        >
        >
        > Thank you very much for this advice. It's first time I see how to use
        > pointers and it is useful as I see but still there are errors in my
        > rewritten code. And i don't know anything about pointers so i can't solve
        > what it mean could you please help me?
        > I haven't much time otherwise i would not annoy you.[/color]

        It isn't annoying me... just a sign my mind isn't focused on
        work yet this morning. :) Sorry I wasn't more clear.
        [color=blue]
        >
        > ERROR:
        > cannot convert `float' to `float*' for argument `1' to `void
        > vymen(float*, float*)'[/color]

        Right -- we've changed the function to take pointers, which means
        you need to call it with pointers (aka the address of x, not x
        itself).
        [color=blue]
        >
        > CODE:
        >
        > #include<stdio. h>
        > #include<math.h >
        >
        > void odd(float x, float y);
        > void change(float *x, float *y);
        >
        > void odd(float x, float y)
        > {
        > int i;
        > if (x>y) change(x,y);[/color]

        if ( x > y ) {
        change(&x, &y);
        }

        Don
        [color=blue]
        > x=roundf(x);
        > y=roundf(y);
        > for(i=1;i<(y-x)+1;i++)
        > if ( fmodf ((x+i),2)==1 || fmodf ((x+i),2)==-1 ) printf( "%f
        > ",(x+i) );
        > }
        >
        > void change(float *x, float *y)
        > {
        > float c;
        > if ( x==NULL || y==NULL ) return;
        > c=*x;
        > *x=*y;
        > *y=c;
        > }
        >
        > main()
        > {
        > float a,b;
        > printf("Type two real numbers :");
        > scanf("%f%f",&a ,&b);
        > odd(a,b);
        > getchar();
        > getchar();
        > }
        >
        >[/color]

        Comment

        • Mac

          #5
          Re: Need HELP

          On Fri, 01 Apr 2005 14:07:53 +0000, Don Morris wrote:
          [color=blue]
          > #define SWAP_FLOAT(floa t __x, float __y ) \[/color]

          Is this a C99 thing? I've never seen a function-like macro defined this
          way (with types) and my compiler won't accept it.

          Maybe you meant to type:
          #define SWAP_FLOAT(__x, __y ) \
          [color=blue]
          > do { \
          > float __temp; \
          > __temp = __x; \
          > __x = __y; \
          > __y = __temp; \
          > } while (0)[/color]

          And why are you using the undercores in the identifier names? They seem
          to me to be completely unnecessary. Couldn't you just do it like this:

          #define SWAP_FLOAT(x, y ) \
          do { \
          float temp; \
          temp = x; \
          x = y; \
          y = temp; \
          } while (0)


          --Mac

          Comment

          • Artie Gold

            #6
            Re: Need HELP

            Mac wrote:[color=blue]
            > On Fri, 01 Apr 2005 14:07:53 +0000, Don Morris wrote:
            >
            >[color=green]
            >>#define SWAP_FLOAT(floa t __x, float __y ) \[/color]
            >
            >
            > Is this a C99 thing? I've never seen a function-like macro defined this
            > way (with types) and my compiler won't accept it.[/color]

            And your compiler is correct![color=blue]
            >
            > Maybe you meant to type:
            > #define SWAP_FLOAT(__x, __y ) \
            >
            >[color=green]
            >>do { \
            >> float __temp; \
            >> __temp = __x; \
            >> __x = __y; \
            >> __y = __temp; \
            >>} while (0)[/color]
            >
            >
            > And why are you using the undercores in the identifier names? They seem
            > to me to be completely unnecessary. Couldn't you just do it like this:[/color]

            Well, it was a misguided attempt at avoiding inadvertent variable
            capture. Identifiers starting with an underscore are reserved for the
            implementation.
            [color=blue]
            >
            > #define SWAP_FLOAT(x, y ) \
            > do { \
            > float temp; \
            > temp = x; \
            > x = y; \
            > y = temp; \
            > } while (0)
            >[/color]
            Consider, however, what happens if you have the following code:

            void nonsensical() {
            float temp = 3.0;
            float other = 4.0;
            printf("before swap, temp = %f, other = %f", temp, other);
            SWAP_FLOAT(temp , other);
            printf("after swap, temp = %f, other = %f", temp, other);
            }

            Macros can be useful -- but (particularly if they declare variables) can
            bite you in the^H^H^H^H^H^H ^H^H^H^H^H^H^H^ H^Hcause problems.

            HTH,
            --ag

            --
            Artie Gold -- Austin, Texas
            http://it-matters.blogspot.com (new post 12/5)

            Comment

            • Old Wolf

              #7
              Re: Need HELP

              Artie Gold wrote:[color=blue]
              > Mac wrote:[color=green]
              > >
              > > #define SWAP_FLOAT(x, y ) \
              > > do { \
              > > float temp; \
              > > temp = x; \
              > > x = y; \
              > > y = temp; \
              > > } while (0)
              > >[/color]
              > Consider, however, what happens if you have the following code:
              >
              > void nonsensical() {
              > float temp = 3.0;
              > float other = 4.0;
              > printf("before swap, temp = %f, other = %f", temp, other);
              > SWAP_FLOAT(temp , other);
              > printf("after swap, temp = %f, other = %f", temp, other);
              > }[/color]

              The problem is that 'temp' in the macro clashes with 'temp' in
              the parameter. So how about this:

              #define SWAP_FLOAT(x, y) \
              do { \
              float x##y; \
              x##y = x; \
              x = y; \
              y = x##y; \
              } while (0)

              No possibility of clashes now (even if 'x' and 'y' are #defined
              to something else already, I think)

              Comment

              • Peter Nilsson

                #8
                Re: Need HELP

                Old Wolf wrote:[color=blue]
                > ...
                > The problem is that 'temp' in the macro clashes with 'temp' in
                > the parameter. So how about this:
                >
                > #define SWAP_FLOAT(x, y) \
                > do { \
                > float x##y; \
                > x##y = x; \
                > x = y; \
                > y = x##y; \
                > } while (0)[/color]

                SWAP_FLOAT(er, rno);
                SWAP_FLOAT(x, *y);

                --
                Peter

                Comment

                • Old Wolf

                  #9
                  Re: Need HELP

                  Peter Nilsson wrote:[color=blue]
                  > Old Wolf wrote:[color=green]
                  > > ...
                  > > The problem is that 'temp' in the macro clashes with 'temp' in
                  > > the parameter. So how about this:
                  > >
                  > > #define SWAP_FLOAT(x, y) \
                  > > do { \
                  > > float x##y; \
                  > > x##y = x; \
                  > > x = y; \
                  > > y = x##y; \
                  > > } while (0)[/color]
                  >
                  > SWAP_FLOAT(er, rno);[/color]

                  No problem, local errno takes precedence over global errno.
                  [color=blue]
                  > SWAP_FLOAT(x, *y);[/color]

                  Ah, serious problem.I guess that takes us back to the
                  pick-something-weird-and-wacky option.

                  Comment

                  • Peter Nilsson

                    #10
                    Re: Need HELP

                    Old Wolf wrote:[color=blue]
                    > Peter Nilsson wrote:[color=green]
                    > > Old Wolf wrote:[color=darkred]
                    > > > ...
                    > > > The problem is that 'temp' in the macro clashes with 'temp' in
                    > > > the parameter. So how about this:
                    > > >
                    > > > #define SWAP_FLOAT(x, y) \
                    > > > do { \
                    > > > float x##y; \
                    > > > x##y = x; \
                    > > > x = y; \
                    > > > y = x##y; \
                    > > > } while (0)[/color]
                    > >
                    > > SWAP_FLOAT(er, rno);[/color]
                    >
                    > No problem, local errno takes precedence over global errno.[/color]

                    You don't seem to realise that, if <errno.h> is included,
                    errno is a _macro_ "...which expands to a modifiable lvalue
                    that has type int". [7.5p2] It needn't expand to the name of
                    a 'global'.
                    [color=blue][color=green]
                    > > SWAP_FLOAT(x, *y);[/color]
                    >
                    > Ah, serious problem.I guess that takes us back to the
                    > pick-something-weird-and-wacky option.[/color]

                    Or to 'inline' under C99, if such an implementation is available.

                    --
                    Peter

                    Comment

                    Working...