negative zeroes in program output?

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

    #1

    negative zeroes in program output?

    Under what circumstances would a C program, containing nothing
    that is not standard C, prefix a zero result of a calculation
    with doubles with a minus sign? I have written a program that
    does operations on matrices. Some, but not all, of the zeroes in
    the result matrices are displayed by printf as -0.0. (I know that
    floating point arithmetic algorithms use positive and negative
    zero but this is the first time I've seen negative zeroes in
    program output.)

  • Mark McIntyre

    #2
    Re: negative zeroes in program output?

    On Wed, 21 Jul 2004 19:41:31 GMT, in comp.lang.c , Elliot Marks
    <emarks@email.n et> wrote:
    [color=blue]
    >Under what circumstances would a C program, containing nothing
    >that is not standard C, prefix a zero result of a calculation
    >with doubles with a minus sign? I have written a program that
    >does operations on matrices. Some, but not all, of the zeroes in
    >the result matrices are displayed by printf as -0.0.[/color]

    Floating point is not exact. What mathematically might be zero is quite
    likely to be 0 +/- some small amount. Your printf format string will then
    round it and display as -0.0

    --
    Mark McIntyre
    CLC FAQ <http://www.eskimo.com/~scs/C-faq/top.html>
    CLC readme: <http://www.ungerhu.com/jxh/clc.welcome.txt >


    ----== Posted via Newsfeed.Com - Unlimited-Uncensored-Secure Usenet News==----
    http://www.newsfeed.com The #1 Newsgroup Service in the World! >100,000 Newsgroups
    ---= 19 East/West-Coast Specialized Servers - Total Privacy via Encryption =---

    Comment

    • Elliot Marks

      #3
      Re: negative zeroes in program output?

      Mark McIntyre wrote:[color=blue]
      > On Wed, 21 Jul 2004 19:41:31 GMT, in comp.lang.c , Elliot Marks
      > <emarks@email.n et> wrote:
      >
      >[color=green]
      >>Under what circumstances would a C program, containing nothing
      >>that is not standard C, prefix a zero result of a calculation
      >>with doubles with a minus sign? I have written a program that
      >>does operations on matrices. Some, but not all, of the zeroes in
      >>the result matrices are displayed by printf as -0.0.[/color]
      >
      >
      > Floating point is not exact. What mathematically might be zero is quite
      > likely to be 0 +/- some small amount. Your printf format string will then
      > round it and display as -0.0
      >[/color]
      I cancelled the original post because this behaviour went away
      after using a different compiler. Your answer makes good sense
      though.

      Thanks,
      Elliot



      Comment

      • E. Robert Tisdale

        #4
        Re: negative zeroes in program output?

        Mark McIntyre wrote:
        [color=blue]
        > Elliot Marks wrote:
        >[color=green]
        >>Under what circumstances would a C program, containing nothing
        >>that is not standard C, prefix a zero result of a calculation
        >>with doubles with a minus sign? I have written a program that
        >>does operations on matrices. Some, but not all, of the zeroes in
        >>the result matrices are displayed by printf as -0.0.[/color]
        >
        > Floating point is not exact. What mathematically might be zero
        > is quite likely to be 0 +/- some small amount.
        > Your printf format string will then round it and display as -0.0[/color]

        No.
        [color=blue]
        > cat main.c[/color]
        #include <stdio.h>

        int main(int argc, char* argv[]) {
        double x = -0.0;
        double y = +0.0;
        fprintf(stdout, "%lf = x\n", x);
        fprintf(stdout, "%lf = y\n", y);
        if (x == y)
        fprintf(stdout, "They are equal!\n");
        return 0;
        }
        [color=blue]
        > gcc -Wall -std=c99 -pedantic -o main main.c
        > ./main[/color]
        -0.000000 = x
        0.000000 = y
        They are equal!

        A floating-point number has two representations for zero --
        one positive and the other negative.

        Comment

        • pete

          #5
          Re: negative zeroes in program output?

          E. Robert Tisdale wrote:[color=blue]
          >
          > Mark McIntyre wrote:
          >[color=green]
          > > Elliot Marks wrote:
          > >[color=darkred]
          > >>Under what circumstances would a C program, containing nothing
          > >>that is not standard C, prefix a zero result of a calculation
          > >>with doubles with a minus sign? I have written a program that
          > >>does operations on matrices. Some, but not all, of the zeroes in
          > >>the result matrices are displayed by printf as -0.0.[/color]
          > >
          > > Floating point is not exact. What mathematically might be zero
          > > is quite likely to be 0 +/- some small amount.
          > > Your printf format string will then round it and display as -0.0[/color]
          >
          > No.[/color]

          That's what I was thinking.
          [color=blue]
          > double x = -0.0;
          > double y = +0.0;
          > fprintf(stdout, "%lf = x\n", x);
          > fprintf(stdout, "%lf = y\n", y);
          > if (x == y)
          > fprintf(stdout, "They are equal!\n");[/color]
          [color=blue]
          > -0.000000 = x
          > 0.000000 = y
          > They are equal!
          >
          > A floating-point number has two representations for zero --
          > one positive and the other negative.[/color]

          It's allowed to have two, but floating point representation
          is implementation defined.

          The '-' character output of your program
          is also implementation defined, even on implementations that
          have two representations for zero --
          one positive and the other negative.

          --
          pete

          Comment

          • Keith Thompson

            #6
            Re: negative zeroes in program output?

            "E. Robert Tisdale" <E.Robert.Tisda le@jpl.nasa.gov > writes:[color=blue]
            > Mark McIntyre wrote:[color=green]
            > > Elliot Marks wrote:[color=darkred]
            > >> Under what circumstances would a C program, containing nothing that
            > >> is not standard C, prefix a zero result of a calculation with
            > >> doubles with a minus sign? I have written a program that does
            > >> operations on matrices. Some, but not all, of the zeroes in the
            > >> result matrices are displayed by printf as -0.0.[/color]
            > > Floating point is not exact. What mathematically might be zero
            > > is quite likely to be 0 +/- some small amount. Your printf format
            > > string will then round it and display as -0.0[/color]
            >
            > No.[/color]

            Yes.
            [color=blue][color=green]
            > > cat main.c[/color]
            > #include <stdio.h>
            >
            > int main(int argc, char* argv[]) {
            > double x = -0.0;
            > double y = +0.0;
            > fprintf(stdout, "%lf = x\n", x);
            > fprintf(stdout, "%lf = y\n", y);
            > if (x == y)
            > fprintf(stdout, "They are equal!\n");
            > return 0;
            > }
            >[color=green]
            > > gcc -Wall -std=c99 -pedantic -o main main.c
            > > ./main[/color]
            > -0.000000 = x
            > 0.000000 = y
            > They are equal![/color]

            Why do you use fprintf(stdout, ...) rather than printf(...)?

            The correct format for type double is "%f". The "%lf" format is not
            defined by the standard, so your first two fprintf calls invoke
            undefined behavior.
            [color=blue]
            > A floating-point number has two representations for zero --
            > one positive and the other negative.[/color]

            That's true for many (most?) existing floating-point representations ,
            but I don't think the C standard says anything about it. An
            implementation for which the above program prints

            0.000000 = x
            0.000000 = y
            They are equal!

            would be conforming as far as I know.

            But the following program:

            #include <stdio.h>
            int main(void)
            {
            double x = -1e-20;
            double y = +1e-20;
            printf("x = %lf\n", x);
            printf("y = %lf\n", y);
            printf(x == y ? "They're equal\n" : "They're not equal\n");
            return 0;
            }

            produces the following output (in at least one implementation) :

            x = -0.000000
            y = 0.000000
            They're not equal

            --
            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

            • pete

              #7
              Re: negative zeroes in program output?

              Keith Thompson wrote:
              [color=blue]
              > The correct format for type double is "%f".[/color]

              Yes.
              [color=blue]
              > The "%lf" format is not defined by the standard,
              > so your first two fprintf calls invoke
              > undefined behavior.[/color]

              Undefined in C89
              Defined in C99


              C89 last public draft:
              4.9.6 Formatted input/output functions
              4.9.6.1 The fprintf function

              an optional l (ell) specifying that a following d , i , o ,
              u , x , or X conversion specifier applies to a long int or unsigned
              long int argument; an optional l specifying that a following n
              conversion specifier applies to a pointer to a long int argument; or
              an optional L specifying that a following e , E , f , g , or G
              conversion specifier applies to a long double argument.
              If an h , l ,
              or L appears with any other conversion specifier, the behavior is
              undefined.

              N869
              7.19.6.1 The fprintf function

              l (ell) ... or has no effect on a following a,
              A, e, E, f, F, g, or G conversion
              specifier.

              --
              pete

              Comment

              • Joe Wright

                #8
                Re: negative zeroes in program output?

                Keith Thompson wrote:

                [ snip ][color=blue]
                >
                > That's true for many (most?) existing floating-point representations ,
                > but I don't think the C standard says anything about it. An
                > implementation for which the above program prints
                >
                > 0.000000 = x
                > 0.000000 = y
                > They are equal!
                >
                > would be conforming as far as I know.
                >
                > But the following program:
                >
                > #include <stdio.h>
                > int main(void)
                > {
                > double x = -1e-20;
                > double y = +1e-20;
                > printf("x = %lf\n", x);
                > printf("y = %lf\n", y);
                > printf(x == y ? "They're equal\n" : "They're not equal\n");
                > return 0;
                > }
                >
                > produces the following output (in at least one implementation) :
                >
                > x = -0.000000
                > y = 0.000000
                > They're not equal
                >[/color]

                That program, on my implementation (gcc 3.1) looks like..

                C:\work\c\clc>k t
                x = 0.000000
                y = 0.000000
                They're not equal

                Negative zero is weird.

                Also on my implementation, "%f" suffices for both double and long
                double. "%lf" is allowed by C99 and accepted quietly by gcc but is
                not defined.

                --
                Joe Wright mailto:joewwrig ht@comcast.net
                "Everything should be made as simple as possible, but not simpler."
                --- Albert Einstein ---

                Comment

                • Keith Thompson

                  #9
                  Re: negative zeroes in program output?

                  pete <pfiland@mindsp ring.com> writes:[color=blue]
                  > Keith Thompson wrote:
                  >[color=green]
                  > > The correct format for type double is "%f".[/color]
                  >
                  > Yes.
                  >[color=green]
                  > > The "%lf" format is not defined by the standard,
                  > > so your first two fprintf calls invoke
                  > > undefined behavior.[/color]
                  >
                  > Undefined in C89
                  > Defined in C99[/color]
                  [snip][color=blue]
                  > N869
                  > 7.19.6.1 The fprintf function
                  >
                  > l (ell) ... or has no effect on a following a,
                  > A, e, E, f, F, g, or G conversion
                  > specifier.[/color]

                  You're right, I missed that. (It's also in the final C99 standard.)

                  --
                  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

                  • Dan Pop

                    #10
                    Re: negative zeroes in program output?

                    In <lnwu0wrbt8.fsf @nuthaus.mib.or g> Keith Thompson <kst-u@mib.org> writes:
                    [color=blue]
                    >pete <pfiland@mindsp ring.com> writes:[color=green]
                    >> Keith Thompson wrote:
                    >>[color=darkred]
                    >> > The correct format for type double is "%f".[/color]
                    >>
                    >> Yes.
                    >>[color=darkred]
                    >> > The "%lf" format is not defined by the standard,
                    >> > so your first two fprintf calls invoke
                    >> > undefined behavior.[/color]
                    >>
                    >> Undefined in C89
                    >> Defined in C99[/color]
                    >[snip][color=green]
                    >> N869
                    >> 7.19.6.1 The fprintf function
                    >>
                    >> l (ell) ... or has no effect on a following a,
                    >> A, e, E, f, F, g, or G conversion
                    >> specifier.[/color]
                    >
                    >You're right, I missed that. (It's also in the final C99 standard.)[/color]

                    Official reason: to improve symmetry between scanf and printf.
                    Unofficial reason: far too much broken code used %lf in printf and
                    practically all implementors ignored the l in this context:

                    fangorn:~/tmp 573> gcc -Wall test.c
                    fangorn:~/tmp 574> gcc -pedantic -Wall test.c
                    test.c: In function `main':
                    test.c:5: warning: ISO C90 does not support the `%lf' printf format

                    Dan
                    --
                    Dan Pop
                    DESY Zeuthen, RZ group
                    Email: Dan.Pop@ifh.de

                    Comment

                    Working...