stringise DBL_DIG

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

    stringise DBL_DIG

    /*
    converts a double to decimal with no loss of accuracy.
    */
    void accurate(char *out, double x)
    {
    char fmt[32];

    sprintf(fmt, "%%.%dg", DBL_DIG);
    sprintf(out, fmt, x);
    }

    Any way of getting rid of the first call to sprintf() ?


  • Ben Pfaff

    #2
    Re: stringise DBL_DIG

    "Malcolm" <malcolm@55bank .freeserve.co.u k> writes:
    [color=blue]
    > sprintf(fmt, "%%.%dg", DBL_DIG);
    > sprintf(out, fmt, x);
    >
    > Any way of getting rid of the first call to sprintf() ?[/color]

    sprintf(out, "%.*g", (int) DBL_DIG, x);
    --
    "I don't have C&V for that handy, but I've got Dan Pop."
    --E. Gibbons

    Comment

    • Malcolm

      #3
      Re: stringise DBL_DIG


      "Ben Pfaff" <blp@cs.stanfor d.edu> wrote in message[color=blue]
      >
      > sprintf(out, "%.*g", (int) DBL_DIG, x);
      >[/color]
      Thanks. I was barking up the wrong tree with the stringise (#) operator,
      which of course gives me the string "DBL_DIG".


      Comment

      • Martin Ambuhl

        #4
        Re: stringise DBL_DIG

        Malcolm wrote:
        [color=blue]
        > /*
        > converts a double to decimal with no loss of accuracy.
        > */
        > void accurate(char *out, double x)
        > {
        > char fmt[32];
        >
        > sprintf(fmt, "%%.%dg", DBL_DIG);
        > sprintf(out, fmt, x);
        > }
        >
        > Any way of getting rid of the first call to sprintf() ?[/color]

        #define ACCURATE(s,x) sprintf((s),"%. *g",DBL_DIG,(x) )


        --
        Martin Ambuhl

        Comment

        • Peter Nilsson

          #5
          Re: stringise DBL_DIG

          "Malcolm" <malcolm@55bank .freeserve.co.u k> wrote in message
          news:bvjpbq$b8c $1@newsg4.svr.p ol.co.uk...[color=blue]
          >
          > "Ben Pfaff" <blp@cs.stanfor d.edu> wrote in message[color=green]
          > >
          > > sprintf(out, "%.*g", (int) DBL_DIG, x);
          > >[/color]
          >
          > Thanks. I was barking up the wrong tree with the stringise (#) operator,
          > which of course gives me the string "DBL_DIG".[/color]

          That's easily fixed (See FAQ 11.17), but you're still in trouble.

          AFAIK, there's nothing barring an implementation from doing any of these in
          a header source...

          #define DBL_DIG __DBL_DIG
          #define DBL_DIG (10)
          #define DBL_DIG (FLT_DIG*2)

          So code like...

          #define STR(x) #x
          #define STRSTR(x) STR(x)

          sprintf(out, "%." STRSTR(DBL_DIG) "g", x);

          ....is not as maximally portable as it might seem.

          --
          Peter


          Comment

          • Old Wolf

            #6
            Re: stringise DBL_DIG

            > > /*[color=blue][color=green]
            > > converts a double to decimal with no loss of accuracy.
            > > */
            > > void accurate(char *out, double x)
            > > {
            > > char fmt[32];
            > >
            > > sprintf(fmt, "%%.%dg", DBL_DIG);
            > > sprintf(out, fmt, x);
            > > }[/color]
            >
            > #define ACCURATE(s,x) sprintf((s),"%. *g",DBL_DIG,(x) )[/color]

            #define ACCURATE(s,n,x) snprintf((s),(n ),"%.*g",DBL_DI G,(x))

            I don't mean to be a spelling nazi, but IMHO a buffer overflow
            (eg. when the code is ported to a system that has a higher
            value for DBL_DIG) is a more serious portability "error"
            than casting malloc (which often does get pointed out on here).

            Please tell me if I should refrain from future comments on this
            issue :)

            Also, you could go
            #define ACCURATE_PF(x) "%.*g",DBL_DIG, (x)
            and then
            printf(ACCURATE _PF(x));
            or
            snprintf(s, n, ACCURATE_PF(x)) ;
            etc.

            Comment

            • Peter Nilsson

              #7
              Re: stringise DBL_DIG

              oldwolf@inspire .net.nz (Old Wolf) wrote in message news:<843a4f78. 0402021315.4efb 61a4@posting.go ogle.com>...[color=blue][color=green][color=darkred]
              > > > /*
              > > > converts a double to decimal with no loss of accuracy.
              > > > */
              > > > void accurate(char *out, double x)
              > > > {
              > > > char fmt[32];
              > > >
              > > > sprintf(fmt, "%%.%dg", DBL_DIG);
              > > > sprintf(out, fmt, x);
              > > > }[/color]
              > >
              > > #define ACCURATE(s,x) sprintf((s),"%. *g",DBL_DIG,(x) )[/color]
              >
              > #define ACCURATE(s,n,x) snprintf((s),(n ),"%.*g",DBL_DI G,(x))
              >
              > I don't mean to be a spelling nazi, but IMHO a buffer overflow
              > (eg. when the code is ported to a system that has a higher
              > value for DBL_DIG) is a more serious portability "error"
              > than casting malloc (which often does get pointed out on here).[/color]

              Only trouble is, snprintf is only available in C99. It's a common
              extension for C90 implementations , but unfortunately, it's return
              value is not consistent across such implementations .
              [color=blue]
              > Please tell me if I should refrain from future comments on this
              > issue :)
              >
              > Also, you could go
              > #define ACCURATE_PF(x) "%.*g",DBL_DIG, (x)
              > and then
              > printf(ACCURATE _PF(x));[/color]

              This is generally not considered good form as it obfuscates the printf
              call.
              [color=blue]
              > or
              > snprintf(s, n, ACCURATE_PF(x)) ;
              > etc.[/color]

              --
              Peter

              Comment

              Working...