sin (M_PI)

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

    #1

    sin (M_PI)

    Hi,
    I am using the following code:
    printf("%g", sin(M_PI))
    and getting 1.22461e-16 instead of zero.
    Does anyone have any idea why, and what I can do about it?

    Thanks,
    Adam
  • mark_bluemel@pobox.com

    #2
    Re: sin (M_PI)

    On 12 Jul, 11:14, Adam <a...@sendnospa m.comwrote:
    Hi,
    I am using the following code:
    printf("%g", sin(M_PI))
    and getting 1.22461e-16 instead of zero.
    Does anyone have any idea why,
    The usual issues with floating point accuracy, I'd think.
    and what I can do about it?
    See if your target implementation has an alternative sin()
    implementation (sinl(), which takes and returns long double, may be
    available for example) and a suitable definition of PI.

    Comment

    • mark_bluemel@pobox.com

      #3
      Re: sin (M_PI)

      On 12 Jul, 11:26, mark_blue...@po box.com wrote:
      On 12 Jul, 11:14, Adam <a...@sendnospa m.comwrote:
      >
      Hi,
      I am using the following code:
      printf("%g", sin(M_PI))
      and getting 1.22461e-16 instead of zero.
      Does anyone have any idea why,
      >
      The usual issues with floating point accuracy, I'd think.
      >
      and what I can do about it?
      >
      See if your target implementation has an alternative sin()
      implementation (sinl(), which takes and returns long double, may be
      available for example) and a suitable definition of PI.
      I must give up replying to myself...

      sinl() is part of the standard and should be available. Finding a good
      definition of PI may be more difficult, but a GNU libc header gives:-

      # define M_PIl 3.1415926535897 932384626433832 795029L /*
      pi */

      Comment

      • santosh

        #4
        Re: sin (M_PI)

        Adam wrote:
        Hi,
        I am using the following code:
        printf("%g", sin(M_PI))
        and getting 1.22461e-16 instead of zero.
        Does anyone have any idea why, and what I can do about it?
        Firstly M_PI is not defined in Standard C, though most implementations
        define it as an extension. You can also compute it's value at runtime
        or define it yourself.

        Secondly make sure you include stdio.h and math.h for printf and sin.
        And try using the %f format specifier.

        Comment

        • Adam

          #5
          Re: sin (M_PI)

          santosh wrote:
          Adam wrote:
          >Hi,
          >I am using the following code:
          >printf("%g", sin(M_PI))
          >and getting 1.22461e-16 instead of zero.
          >Does anyone have any idea why, and what I can do about it?
          >
          Firstly M_PI is not defined in Standard C, though most implementations
          define it as an extension. You can also compute it's value at runtime
          or define it yourself.
          >
          Secondly make sure you include stdio.h and math.h for printf and sin.
          And try using the %f format specifier.
          >
          Using %f works, but isn't a suitable solution, as my code is actually
          printf("%g", sin(x)), where x could be pi, or something else, and %f
          messes up the formatting for the other possibilities for x.

          Comment

          • santosh

            #6
            Re: sin (M_PI)

            Adam wrote:
            santosh wrote:
            Adam wrote:
            Hi,
            I am using the following code:
            printf("%g", sin(M_PI))
            and getting 1.22461e-16 instead of zero.
            Does anyone have any idea why, and what I can do about it?
            Firstly M_PI is not defined in Standard C, though most implementations
            define it as an extension. You can also compute it's value at runtime
            or define it yourself.

            Secondly make sure you include stdio.h and math.h for printf and sin.
            And try using the %f format specifier.
            Using %f works, but isn't a suitable solution, as my code is actually
            printf("%g", sin(x)), where x could be pi, or something else, and %f
            messes up the formatting for the other possibilities for x.
            One possibility is to compare x with M_PI and if they're near enough,
            print zero.
            Something like:

            if(abs(M_PI - x) <= delta) puts("0000e0");

            Comment

            • Jens Thoms Toerring

              #7
              Re: sin (M_PI)

              Adam <adam@sendnospa m.comwrote:
              I am using the following code:
              printf("%g", sin(M_PI))
              and getting 1.22461e-16 instead of zero.
              Does anyone have any idea why, and what I can do about it?
              Pi is an irrational number, i.e. you can't write it down
              exactly without giving an infinite number of digits (what-
              ever number system you use). Computers can't deal with
              irrational numbers very well (i.e. at all) since in a
              computer you can only store a finite number of digits.
              Thus what you use for pi is never the true value of pi
              but an approximation. So you can't expect more that an
              approximation of the value of sin of pi when you use an
              approximation of pi to start with.

              Whenever you use floating point numbers you must consider
              that the computer only stores a limited number of (binary)
              digits. In many cases the number of digits that can be
              stored is less than the true number of digits of the
              floating point number - rather obvious for irrational
              numbers like pi, but even a simple looking number like 0.1
              becomes a number with infinitely many digits when expressed
              in binary (like 1/3 has an infinite number of digits when
              written in decimal). Thus in many (if not most) cases you
              do calculations with approximations only. And that's not
              the end of it. E.g. function like sin are computed using
              (clever) approximate algorithms (which tend to be a limi-
              ted number of summands of an infinite sum). So you do ap-
              proximate calculations of functions on approximate values.
              And the result is, of course, that you end up with more or
              less good approximate results. And when you think of it,
              1e-16 is a rather good approximation for a 0 when you con-
              sider the range [-1:1] of the sin function.

              Thus if you do floating point calculations you have to be
              aware of the approximate nature of such computations. And
              you have to be aware that small errors due to the approxi-
              mations can sum up considerably - if you aren't careful
              you can end up with completely bogus results.

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

              Comment

              • santosh

                #8
                Re: sin (M_PI)

                santosh wrote:
                Adam wrote:
                santosh wrote:
                Adam wrote:
                >Hi,
                >I am using the following code:
                >printf("%g", sin(M_PI))
                >and getting 1.22461e-16 instead of zero.
                >Does anyone have any idea why, and what I can do about it?
                >
                Firstly M_PI is not defined in Standard C, though most implementations
                define it as an extension. You can also compute it's value at runtime
                or define it yourself.
                >
                Secondly make sure you include stdio.h and math.h for printf and sin.
                And try using the %f format specifier.
                >
                Using %f works, but isn't a suitable solution, as my code is actually
                printf("%g", sin(x)), where x could be pi, or something else, and %f
                messes up the formatting for the other possibilities for x.
                >
                One possibility is to compare x with M_PI and if they're near enough,
                print zero.
                Something like:
                >
                if(abs(M_PI - x) <= delta) puts("0000e0");
                Sorry about that. Use fabs instead of abs:

                if(fabs(M_PI - x) <= delta) printf("%g\n", 0.0);

                Comment

                • Eric Sosman

                  #9
                  Re: sin (M_PI)

                  Adam wrote:
                  Hi,
                  I am using the following code:
                  printf("%g", sin(M_PI))
                  and getting 1.22461e-16 instead of zero.
                  Does anyone have any idea why, and what I can do about it?
                  Ponder these questions:

                  1: Is M_PI exactly equal to pi, or is it equal to pi+x
                  for some small x?

                  2: What is the value of sin(pi+x)?

                  --
                  Eric Sosman
                  esosman@ieee-dot-org.invalid

                  Comment

                  • Tim Prince

                    #10
                    Re: sin (M_PI)

                    Adam wrote:
                    Hi,
                    I am using the following code:
                    printf("%g", sin(M_PI))
                    and getting 1.22461e-16 instead of zero.
                    Does anyone have any idea why, and what I can do about it?
                    As the other responders have pointed out, this is to be expected. If you
                    had opened up your search engine, you surely would have found some close
                    references.
                    As you haven't said anything about your goals for modifying this
                    behavior, the suggestion about sinl(M_PIl) is as good as any, keeping in
                    mind that default Windows behavior is for long double to be simply an
                    alias for double.

                    Think about the steps you are taking here.
                    M_PI (not defined in std C) is likely a truncated decimal approximation
                    to the irrational value of pi.
                    The argument to sin() is at best the nearest binary value to the decimal
                    value. It could be as much as DBL_EPSILON larger or smaller than the
                    ideal value. A little application of high school math should help you
                    figure out how much difference this makes to the ideal value of sin().

                    If you are writing the code for a compiler to use in constant
                    propagation, say for a target processor like x87 which has some built-in
                    extra precision constants, you could take the position that you should
                    pick the closest of those built-in constants, when it satisfies the
                    demands of the C standard for closeness to the value in question. This
                    would enable the compiler to evaluate sin(M_PI) as 0. at compile time,
                    but then you would have a discrepancy against the behavior of values
                    generated at run time. Unless you want to write a sin() function which
                    searches for a match to certain multiples of the built-in pi before
                    evaluation. Where do you draw the line? pi/4,..., INT_MAX/4*PI ?

                    I understand there has been academic work on the precision attainable by
                    math functions including sin(). When people are building careers on this
                    subject, can you seriously ask "does anyone have any idea?"

                    Comment

                    • osmium

                      #11
                      Re: sin (M_PI)

                      "Jens Thoms Toerring" wrote:
                      Adam <adam@sendnospa m.comwrote:
                      >I am using the following code:
                      >printf("%g", sin(M_PI))
                      >and getting 1.22461e-16 instead of zero.
                      >Does anyone have any idea why, and what I can do about it?
                      >
                      Pi is an irrational number, i.e. you can't write it down
                      exactly without giving an infinite number of digits (what-
                      ever number system you use)
                      One nitpick. I think pi is transcendental rather than irrational.




                      Comment

                      • jacob navia

                        #12
                        Re: sin (M_PI)

                        Tim Prince wrote:
                        Adam wrote:
                        >Hi,
                        >I am using the following code:
                        >printf("%g", sin(M_PI))
                        >and getting 1.22461e-16 instead of zero.
                        >Does anyone have any idea why, and what I can do about it?
                        >
                        As the other responders have pointed out, this is to be expected. If you
                        had opened up your search engine, you surely would have found some close
                        references.
                        As you haven't said anything about your goals for modifying this
                        behavior, the suggestion about sinl(M_PIl) is as good as any, keeping in
                        mind that default Windows behavior is for long double to be simply an
                        alias for double.
                        This is wrong. The lcc-win32 compiler features full precision (80 bits
                        floating point) for long double. The long double equals double
                        feature is just a feature of one compiler system under windows:
                        Microsoft MSVC. Other compilers under windows offer more precision.

                        jacob

                        Comment

                        • Richard Bos

                          #13
                          Re: sin (M_PI)

                          "osmium" <r124c4u102@com cast.netwrote:
                          "Jens Thoms Toerring" wrote:
                          >
                          Adam <adam@sendnospa m.comwrote:
                          I am using the following code:
                          printf("%g", sin(M_PI))
                          and getting 1.22461e-16 instead of zero.
                          Does anyone have any idea why, and what I can do about it?
                          Pi is an irrational number, i.e. you can't write it down
                          exactly without giving an infinite number of digits (what-
                          ever number system you use)
                          >
                          One nitpick. I think pi is transcendental rather than irrational.
                          >
                          http://en.wikipedia.org/wiki/Lindema...strass_theorem
                          Transcendental, and _therefore_ irrational. The transcendental numbers
                          are a strict subset of the rational ones.

                          Richard

                          Comment

                          • Richard Heathfield

                            #14
                            Re: sin (M_PI)

                            Adam said:
                            Hi,
                            I am using the following code:
                            printf("%g", sin(M_PI))
                            and getting 1.22461e-16 instead of zero.
                            Does anyone have any idea why, and what I can do about it?
                            Presumably M_PI represents a value close to pi. It cannot represent pi
                            exactly, because pi is irrational. Given the nature of a sine wave, you
                            can expect sin(reasonable_ approximation_t o_pi) to be a reasonable
                            approximation to 0, and indeed that is what you are getting.

                            If you want to round the value, decide at which decimal place or
                            significant figure you wish to round it, and whether you wish to round
                            it up, down, or nearest. Then write code to do the rounding for you.

                            --
                            Richard Heathfield <http://www.cpax.org.uk >
                            Email: -www. +rjh@
                            Google users: <http://www.cpax.org.uk/prg/writings/googly.php>
                            "Usenet is a strange place" - dmr 29 July 1999

                            Comment

                            • osmium

                              #15
                              Re: sin (M_PI)

                              "Richard Bos" writes:
                              "osmium" <r124c4u102@com cast.netwrote:
                              >
                              >"Jens Thoms Toerring" wrote:
                              >>
                              Adam <adam@sendnospa m.comwrote:
                              >I am using the following code:
                              >printf("%g", sin(M_PI))
                              >and getting 1.22461e-16 instead of zero.
                              >Does anyone have any idea why, and what I can do about it?
                              >
                              Pi is an irrational number, i.e. you can't write it down
                              exactly without giving an infinite number of digits (what-
                              ever number system you use)
                              >>
                              >One nitpick. I think pi is transcendental rather than irrational.
                              >>
                              >http://en.wikipedia.org/wiki/Lindema...strass_theorem
                              >
                              Transcendental, and _therefore_ irrational. The transcendental numbers
                              are a strict subset of the rational ones.
                              I already said it was a nitpick. But the subject of the thread *is*
                              precision, so one should use the most precise word. "Apple" is more precise
                              than "fruit".


                              Comment

                              Working...