Initializing constants

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

    #16
    Re: Initializing constants

    Walter Roberson wrote:
    You've been talking about hardware PI and so on, but you have
    neglected to discuss rounding modes.
    This could be a prolonged discussion on a math library group, but, C
    provides simple long double operators (*, /, etc.). Presumably the
    constants would be implemented for the target/mode used for these
    operations. On the x87, the constant value is independent of the
    rounding/ chopping mode, "hardwired in", and has full accuracy. I'm not
    sure about other hardware.

    Comment

    • newsposter0123

      #17
      Re: Initializing constants

      Skarmander wrote:
      newsposter0123 wrote:
      >Skarmander wrote:
      >>
      <snip>
      >>In this case, simply requiring that a particular macro expand to the
      >>constant pi with a particular platform-dependent precision doesn't seem
      >>too much of a burden on would-be porters.
      >Or even for addition to compilers.
      >>
      Sure. And now I want e, Planck's constant and the square root of 12 to
      some platform-defined precision, and the guy behind me has a whole class
      of expressions he'd like to be evaluated at compile time...
      >
      It has to stop somewhere. Like I said, M_PI is provided on many
      platforms, though it doesn't come with any guarantees as far as I'm
      aware, and it usually has double precision, not long double precision.
      >
      I'm beginning to think that using available math libraries is the best
      solution if doubles do not work for a specific application. Long
      doubles just do not have the same portability yet.

      Comment

      • Ben Pfaff

        #18
        Re: Initializing constants

        "newsposter0123 " <newsposter0123 @yahoo.comwrite s:
        I'm beginning to think that using available math libraries is the best
        solution if doubles do not work for a specific application. Long
        doubles just do not have the same portability yet.
        Long double has been in the C standard since 1989. If they
        aren't portable now, by your standards, then they may never be.
        --
        int main(void){char p[]="ABCDEFGHIJKLM NOPQRSTUVWXYZab cdefghijklmnopq rstuvwxyz.\
        \n",*q="kl BIcNBFr.NKEzjwC IxNJC";int i=sizeof p/2;char *strchr();int putchar(\
        );while(*q){i+= strchr(p,*q++)-p;if(i>=(int)si zeof p)i-=sizeof p-1;putchar(p[i]\
        );}return 0;}

        Comment

        • jacob navia

          #19
          Re: Initializing constants

          Skarmander wrote:
          newsposter0123 wrote:
          >
          >Skarmander wrote:
          >>
          <snip>
          >
          >>In this case, simply requiring that a particular macro expand to the
          >>constant pi with a particular platform-dependent precision doesn't seem
          >>too much of a burden on would-be porters.
          >>
          >Or even for addition to compilers.
          >>
          Sure. And now I want e, Planck's constant and the square root of 12 to
          some platform-defined precision, and the guy behind me has a whole class
          of expressions he'd like to be evaluated at compile time...
          >
          It has to stop somewhere. Like I said, M_PI is provided on many
          platforms, though it doesn't come with any guarantees as far as I'm
          aware, and it usually has double precision, not long double precision.
          >
          S.
          Yes, and that can be a problem. One of the ways to solve that is

          #define M_PI 3.1415926535897 9323846
          #define M_PIL 3.1415926535897 932384626433832 795029L

          Since those identifiers are not standard, it is difficult to propose
          this. In lcc-win32 this is only defined if you are NOT in -ansic
          mode.

          But obviously this MUST stop somewhere as you said. One of the
          best solutions would be to define all constants in long double
          precision:
          #define M_PI_2 1.5707963267948 966192313216916 397514L /* pi/2 */
          but that could make that expressions are promoted to long double
          precision and done in higher precision.

          To avoid that, you can ((double)M_PI_2 ), but this is difficult too,
          since many compilers (lcc-win32 included) do not respect this cast
          sometimes.

          Yes numerical analysis and numerical software is quite a mess.

          jacob

          Comment

          • CBFalconer

            #20
            Re: Initializing constants

            Ben Pfaff wrote:
            "newsposter0123 " <newsposter0123 @yahoo.comwrite s:
            >
            >I'm beginning to think that using available math libraries is the
            >best solution if doubles do not work for a specific application.
            >Long doubles just do not have the same portability yet.
            >
            Long double has been in the C standard since 1989. If they
            aren't portable now, by your standards, then they may never be.
            #define PI (355.0 / 155) /* to 7 sig. digits */

            :-)

            --
            Some informative links:
            news:news.annou nce.newusers
            Latest news coverage, email, free stock quotes, live scores and video are just the beginning. Discover more every day at Yahoo!






            Comment

            • newsposter0123

              #21
              Re: Initializing constants

              CBFalconer wrote:
              >
              #define PI (355.0 / 155) /* to 7 sig. digits */
              >
              The C standard used to require all constants to be doubles. It probably
              now requires them to be long doubles. However, sizeof(float) >
              sizeof(double) sizeof(long dobule) is not guaranteed. Nor does it
              require the compiler itself to use a specific size of long double. In
              the extreme case of the compiler using 32bit floats/doubles/long
              doubles (that generally have precision 6 digits of accuracy) to create
              64 or even 128 bit long doubles, this would only result in (at best) 5
              digits of accuracy. Most modern, mainstream compilers would use >=
              64bit doubles/ long doubles and create the proper binary representation
              that would convert to 7 significant digits in base 10, and print
              accordingly. This is certainly the means to implement the default (3)
              case in previous post.

              Comment

              • Skarmander

                #22
                Re: Initializing constants

                newsposter0123 wrote:
                CBFalconer wrote:
                >#define PI (355.0 / 155) /* to 7 sig. digits */
                >>
                The C standard used to require all constants to be doubles. It probably
                now requires them to be long doubles.
                It doesn't, even if we restrict ourselves to floating-point constants. You
                must not have been reading this thread closely, since an example was
                mentioned elsewhere by Jacob Navia:

                #define M_PI 3.1415926535897 9323846
                #define M_PIL 3.1415926535897 932384626433832 795029L

                The "f" suffix forms float constants, the "l" suffix long double constants,
                and no suffix forms double constants.
                However, sizeof(float) sizeof(double) sizeof(long dobule) is not
                guaranteed.
                Correct, but DBL_DIG >= FLT_DIG *is* guaranteed ("double" must have at least
                10 digits precision; "float" at least 6).
                Nor does it require the compiler itself to use a specific size of long
                double.
                It wouldn't be logical to do so either; some platforms don't have an
                extended floating-point type. Those that do wouldn't be served well by an
                arbitrary size demand (floating-point types show much more variation than
                the integral types).

                C99 adds a way for implementations to signal that they implement IEEE 60559
                for floating-point. This gives you a few more guarantees about
                floating-point; in particular, "long double" is required to be an IEEE
                extended type (bigger than double, in any case).
                In the extreme case of the compiler using 32bit floats/doubles/long
                doubles (that generally have precision 6 digits of accuracy) to create 64
                or even 128 bit long doubles, this would only result in (at best) 5
                digits of accuracy.
                Your statement is too ambiguous to make much sense of, but I suspect adding
                a suffix would solve whatever problems you allude to.
                Most modern, mainstream compilers would use >= 64bit doubles/ long
                doubles and create the proper binary representation that would convert to
                7 significant digits in base 10, and print accordingly. This is certainly
                the means to implement the default (3) case in previous post.
                >
                I still get the impression that you want guarantees the standard doesn't
                give you for a very good reason. The canonical way of solving that is to
                demand those guarantees from the implementation as a prerequisite for
                portability (to increase portability, the guarantees should be "at least" to
                allow the program to fit itself to a platform).

                If you need a minimum precision for "long double", say so in your
                requirements. If you need a compile-time floating-point constant
                representing the value of pi in some platform-dependent precision, say so in
                your requirements. If you don't *need* anything but would like to *use*
                optional features you expect most platforms to have, write your own API for
                them and make its implementation optional (with a way of signalling that
                it's not implemented).

                From your previous posts, I get the impression that you're demanding
                portability where the standard cannot reasonably give it to you. One aspect
                of C programming is that C quite possibly has the widest platform base of
                any programming language, and its philosophy (part of it, at least) is to
                give programmers a language that can be implemented efficiently and can be
                used to implement efficient, portable programs. To achieve this it
                guarantees less than programmers would like; that's a feature, not a bug.

                S.

                Comment

                • newsposter0123

                  #23
                  Re: Initializing constants

                  Skarmander wrote:
                  newsposter0123 wrote:
                  >CBFalconer wrote:
                  >>#define PI (355.0 / 155) /* to 7 sig. digits */
                  >>>
                  >The C standard used to require all constants to be doubles.
                  I should qualify this as (now obsolete) K&R C required all floating
                  constants to be double.
                  It probably
                  >now requires them to be long doubles.
                  >
                  It doesn't, even if we restrict ourselves to floating-point constants.
                  Of course floating point constants.
                  You must not have been reading this thread closely, since an example was
                  mentioned elsewhere by Jacob Navia:
                  >
                  #define M_PI 3.1415926535897 9323846
                  #define M_PIL 3.1415926535897 932384626433832 795029L
                  >
                  The "f" suffix forms float constants, the "l" suffix long double
                  constants, and no suffix forms double constants.
                  Yep, but the C99 standard only recommends that the compile time
                  creation of floating point constants at least match the run-time
                  library functions/ conversions. If C99 required that compile time
                  creation of floating point constants use a precision greater than the
                  maximum available at run-time, then any floating point constant could
                  be represented, in binary, accurate to the least significant bit (of
                  the mantissa).
                  >
                  >However, sizeof(float) sizeof(double) sizeof(long dobule) is not
                  >guaranteed.
                  >
                  Correct, but DBL_DIG >= FLT_DIG *is* guaranteed ("double" must have at
                  least 10 digits precision; "float" at least 6).
                  >
                  Just found that in section 5.2.4 of C99. And, LDBL_DIG is guaranteed to
                  at least equal DBL_DIG. This guarantees that (in theory anyway) most
                  accurate constants of type float can be created, at run-time, from type
                  long double.
                  C99 adds a way for implementations to signal that they implement IEEE
                  60559 for floating-point. This gives you a few more guarantees about
                  floating-point; in particular, "long double" is required to be an IEEE
                  extended type (bigger than double, in any case).
                  And for complex numbers, but thats still yet another flame on some
                  other group.
                  I still get the impression that you want guarantees the standard doesn't
                  give you for a very good reason. The canonical way of solving that is to
                  demand those guarantees from the implementation as a prerequisite for
                  portability (to increase portability, the guarantees should be "at
                  least" to allow the program to fit itself to a platform).
                  >
                  If you need a minimum precision for "long double", say so in your
                  requirements. If you need a compile-time floating-point constant
                  representing the value of pi in some platform-dependent precision, say
                  so in your requirements. If you don't *need* anything but would like to
                  *use* optional features you expect most platforms to have, write your
                  own API for them and make its implementation optional (with a way of
                  signalling that it's not implemented).
                  >
                  From your previous posts, I get the impression that you're demanding
                  portability where the standard cannot reasonably give it to you. One
                  aspect of C programming is that C quite possibly has the widest platform
                  base of any programming language, and its philosophy (part of it, at
                  least) is to give programmers a language that can be implemented
                  efficiently and can be used to implement efficient, portable programs.
                  To achieve this it guarantees less than programmers would like; that's a
                  feature, not a bug.
                  >
                  I'm not really demanding guarantees. Just looking for a means of
                  obtaining a most accurate read-only long double constant for a given
                  run-time environment in a portable way.

                  Comment

                  • Keith Thompson

                    #24
                    Re: Initializing constants

                    Skarmander <invalid@dontma ilme.comwrites:
                    [...]
                    This is why it's impossible for a compiler to allow
                    const long x = foo();
                    with foo() an arbitrary function, because to solve this in general,
                    the compiler would have to be capable of deferring translation of the
                    entire program! A C *interpreter* could do it, but that's probably not
                    what you're looking for.
                    Ahem.
                    =============== =============== ==
                    #include <stdio.h>

                    long foo(void)
                    {
                    return 42;
                    }

                    int main(void)
                    {
                    const long x = foo();
                    printf("x = %ld\n", x);
                    return 0;
                    }
                    =============== =============== ==

                    The output is:

                    x = 42

                    "const" does *not* mean "constant" in C; it means read-only. The
                    const qualifier on the declaration of x only means that assigning a
                    value to x is a constraint violation, and modifying it indirectly by
                    subverting the "const" qualification:

                    *(long*)&x = 43;

                    invokes undefined behavior. It does not require the expression to be
                    evaluated at compile time (though, as always, the compiler is free to
                    do so by the "as-if" rule).

                    --
                    Keith Thompson (The_Other_Keit h) kst-u@mib.org <http://www.ghoti.net/~kst>
                    San Diego Supercomputer Center <* <http://users.sdsc.edu/~kst>
                    We must do something. This is something. Therefore, we must do this.

                    Comment

                    • Keith Thompson

                      #25
                      Re: Initializing constants

                      CBFalconer <cbfalconer@yah oo.comwrites:
                      Ben Pfaff wrote:
                      >"newsposter012 3" <newsposter0123 @yahoo.comwrite s:
                      >>
                      >>I'm beginning to think that using available math libraries is the
                      >>best solution if doubles do not work for a specific application.
                      >>Long doubles just do not have the same portability yet.
                      >>
                      >Long double has been in the C standard since 1989. If they
                      >aren't portable now, by your standards, then they may never be.
                      >
                      #define PI (355.0 / 155) /* to 7 sig. digits */
                      >
                      :-)
                      Sure, if by "7" you mean "1".

                      I think you're looking for (355.0 / 113).

                      --
                      Keith Thompson (The_Other_Keit h) kst-u@mib.org <http://www.ghoti.net/~kst>
                      San Diego Supercomputer Center <* <http://users.sdsc.edu/~kst>
                      We must do something. This is something. Therefore, we must do this.

                      Comment

                      • Skarmander

                        #26
                        Re: Initializing constants

                        Keith Thompson wrote:
                        Skarmander <invalid@dontma ilme.comwrites:
                        [...]
                        >This is why it's impossible for a compiler to allow
                        > const long x = foo();
                        >with foo() an arbitrary function, because to solve this in general,
                        >the compiler would have to be capable of deferring translation of the
                        >entire program! A C *interpreter* could do it, but that's probably not
                        >what you're looking for.
                        >
                        Ahem.
                        =============== =============== ==
                        #include <stdio.h>
                        >
                        long foo(void)
                        {
                        return 42;
                        }
                        >
                        int main(void)
                        {
                        const long x = foo();
                        My bad. I should have made clear that we were still talking about objects
                        with static storage duration, hence the need for the initializer to be a
                        constant expression. (I was exactly discussing the confusion between
                        constant expressions and const-qualified objects.)

                        S.

                        Comment

                        • Richard Tobin

                          #27
                          Re: Initializing constants

                          In article <lnu03pevh1.fsf @nuthaus.mib.or g>,
                          Keith Thompson <kst-u@mib.orgwrote:
                          >#define PI (355.0 / 155) /* to 7 sig. digits */
                          >Sure, if by "7" you mean "1".
                          Um, 0 actually. 355/155 is about 2.3.

                          -- Richard

                          Comment

                          • Keith Thompson

                            #28
                            Re: Initializing constants

                            richard@cogsci. ed.ac.uk (Richard Tobin) writes:
                            In article <lnu03pevh1.fsf @nuthaus.mib.or g>,
                            Keith Thompson <kst-u@mib.orgwrote:
                            >
                            >>#define PI (355.0 / 155) /* to 7 sig. digits */
                            >
                            >>Sure, if by "7" you mean "1".
                            >
                            Um, 0 actually. 355/155 is about 2.3.
                            Pedant!

                            --
                            Keith Thompson (The_Other_Keit h) kst-u@mib.org <http://www.ghoti.net/~kst>
                            San Diego Supercomputer Center <* <http://users.sdsc.edu/~kst>
                            We must do something. This is something. Therefore, we must do this.

                            Comment

                            • Joe Wright

                              #29
                              Re: Initializing constants

                              Richard Tobin wrote:
                              In article <lnu03pevh1.fsf @nuthaus.mib.or g>,
                              Keith Thompson <kst-u@mib.orgwrote:
                              >
                              >>#define PI (355.0 / 155) /* to 7 sig. digits */
                              >
                              >Sure, if by "7" you mean "1".
                              >
                              Um, 0 actually. 355/155 is about 2.3.
                              >
                              -- Richard
                              2.2903225806451 615

                              --
                              Joe Wright
                              "Everything should be made as simple as possible, but not simpler."
                              --- Albert Einstein ---

                              Comment

                              • CBFalconer

                                #30
                                Re: Initializing constants

                                Keith Thompson wrote:
                                CBFalconer <cbfalconer@yah oo.comwrites:
                                >Ben Pfaff wrote:
                                >>"newsposter01 23" <newsposter0123 @yahoo.comwrite s:
                                >>>
                                >>>I'm beginning to think that using available math libraries is the
                                >>>best solution if doubles do not work for a specific application.
                                >>>Long doubles just do not have the same portability yet.
                                >>>
                                >>Long double has been in the C standard since 1989. If they
                                >>aren't portable now, by your standards, then they may never be.
                                >>
                                >#define PI (355.0 / 155) /* to 7 sig. digits */
                                >>
                                >:-)
                                >
                                Sure, if by "7" you mean "1".
                                >
                                I think you're looking for (355.0 / 113).
                                My face now bears a close resemblence to a beet. That'll teach me
                                to rely on memory.

                                --
                                Chuck F (cbfalconer at maineline dot net)
                                Available for consulting/temporary embedded and systems.
                                <http://cbfalconer.home .att.net>


                                Comment

                                Working...