Signed int -0 ?

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Christian Stigen Larsen

    Signed int -0 ?

    A signed int reserves one bit to signify whether a number is positive or
    negative. In light of this, a colleague asked me whether there existed an
    int in C++ that was -0, a zero with the negative bit set. I was intrigued
    by this, so I tried the following code:

    #include <stdio.h>

    int main(int, char**) {
    int a(-0);
    printf("a=%d\n" , a);
    if ( a==0 ) printf("a==0\n" );
    if ( a==-0 ) printf("a==-0\n");
    return 0;
    }

    The output is:

    a=0
    a==0
    a==-0

    So it seems that no such number can be used in C++, and speaking of
    mathematical numbers, it makes perfect sense, but what is actually going on
    "behing the curtains" in C++ since the compiled code can't discern between
    +0 and -0 ?

    --
    Christian Stigen Larsen -- http://sublevel3.org/~csl/
  • Thore B. Karlsen

    #2
    Re: Signed int -0 ?

    On Thu, 3 Jul 2003 13:38:13 +0000 (UTC), cslarsen@newsca che.ntnu.no
    (Christian Stigen Larsen) wrote:
    [color=blue]
    >A signed int reserves one bit to signify whether a number is positive or
    >negative. In light of this, a colleague asked me whether there existed an
    >int in C++ that was -0, a zero with the negative bit set. I was intrigued
    >by this, so I tried the following code:
    >
    > #include <stdio.h>
    >
    > int main(int, char**) {
    > int a(-0);
    > printf("a=%d\n" , a);
    > if ( a==0 ) printf("a==0\n" );
    > if ( a==-0 ) printf("a==-0\n");
    > return 0;
    > }
    >
    >The output is:
    >
    > a=0
    > a==0
    > a==-0
    >
    >So it seems that no such number can be used in C++, and speaking of
    >mathematical numbers, it makes perfect sense, but what is actually going on
    >"behing the curtains" in C++ since the compiled code can't discern between
    >+0 and -0 ?[/color]

    Search for "two's complement" and you'll see. It's not just as simple as
    reserving a bit for the sign.

    --
    Be seeing you.

    Comment

    • Rolf Magnus

      #3
      Re: Signed int -0 ?

      Christian Stigen Larsen wrote:
      [color=blue]
      > A signed int reserves one bit to signify whether a number is positive
      > or
      > negative. In light of this, a colleague asked me whether there
      > existed an
      > int in C++ that was -0, a zero with the negative bit set. I was
      > intrigued by this, so I tried the following code:
      >
      > #include <stdio.h>
      >
      > int main(int, char**) {
      > int a(-0);
      > printf("a=%d\n" , a);
      > if ( a==0 ) printf("a==0\n" );
      > if ( a==-0 ) printf("a==-0\n");
      > return 0;
      > }
      >
      > The output is:
      >
      > a=0
      > a==0
      > a==-0
      >
      > So it seems that no such number can be used in C++, and speaking of
      > mathematical numbers, it makes perfect sense, but what is actually
      > going on "behing the curtains" in C++ since the compiled code can't
      > discern between +0 and -0 ?[/color]

      Negative numbers are usually expressed as 2's complement, where e.g. an
      8 bit number can represent values from -128 to +127, including onle one
      possible value for 0. It's not just one sign bit that is different.

      Btw: Somehow, but not totally unrelated, in floating point units, there
      actually often is +0 and -0, so while e.g. 1-1 is 0, I think -1+1
      results in -0. This can be useful in some calculations.

      Comment

      • Ron Natalie

        #4
        Re: Signed int -0 ?


        "Christian Stigen Larsen" <cslarsen@newsc ache.ntnu.no> wrote in message news:slrnbg8ce5 .fcg.cslarsen@g aupe.stud.ntnu. no...[color=blue]
        > A signed int reserves one bit to signify whether a number is positive or
        > negative. In light of this, a colleague asked me whether there existed an
        > int in C++ that was -0, a zero with the negative bit set. I was intrigued
        > by this, so I tried the following code:
        >[/color]
        There are several singed integer representations that are possible. While
        the positive numbers are all pretty straight forward binary (this is required
        by the standard), the negatives can be handled in a number of ways.
        Some of thse have the possiblity for a negative zero value. However, the
        most common representation used today is called "two's complement".
        Two's complement has no negative zero, but it does have one more
        negative value available than positive. That is, an 8 bit twos complement
        number goes from -128 to 127.


        Comment

        • Victor Bazarov

          #5
          Re: Signed int -0 ?

          "Rolf Magnus" <ramagnus@t-online.de> wrote...[color=blue]
          > Christian Stigen Larsen wrote:
          >[color=green]
          > > A signed int reserves one bit to signify whether a number is positive
          > > or
          > > negative. In light of this, a colleague asked me whether there
          > > existed an
          > > int in C++ that was -0, a zero with the negative bit set. I was
          > > intrigued by this, so I tried the following code:
          > >
          > > #include <stdio.h>
          > >
          > > int main(int, char**) {
          > > int a(-0);
          > > printf("a=%d\n" , a);
          > > if ( a==0 ) printf("a==0\n" );
          > > if ( a==-0 ) printf("a==-0\n");
          > > return 0;
          > > }
          > >
          > > The output is:
          > >
          > > a=0
          > > a==0
          > > a==-0
          > >
          > > So it seems that no such number can be used in C++, and speaking of
          > > mathematical numbers, it makes perfect sense, but what is actually
          > > going on "behing the curtains" in C++ since the compiled code can't
          > > discern between +0 and -0 ?[/color]
          >
          > Negative numbers are usually expressed as 2's complement, where e.g. an
          > 8 bit number can represent values from -128 to +127, including onle one
          > possible value for 0. It's not just one sign bit that is different.[/color]

          Both signed magnitude representation and 1's complement (which are,
          IIRC, also allowed) have -0.

          Victor


          Comment

          • tom_usenet

            #6
            Re: Signed int -0 ?

            On Thu, 3 Jul 2003 13:38:13 +0000 (UTC), cslarsen@newsca che.ntnu.no
            (Christian Stigen Larsen) wrote:
            [color=blue]
            >A signed int reserves one bit to signify whether a number is positive or
            >negative.[/color]

            On the contrary, it doesn't do that for the most common
            representation, 2s complement.

            In light of this, a colleague asked me whether there existed an[color=blue]
            >int in C++ that was -0, a zero with the negative bit set. I was intrigued
            >by this, so I tried the following code:
            >
            > #include <stdio.h>
            >
            > int main(int, char**) {
            > int a(-0);
            > printf("a=%d\n" , a);
            > if ( a==0 ) printf("a==0\n" );
            > if ( a==-0 ) printf("a==-0\n");
            > return 0;
            > }
            >
            >The output is:
            >
            > a=0
            > a==0
            > a==-0[/color]

            That is the required output, regardless of the integer representation
            used. (0 == -0 must be true).
            [color=blue]
            >
            >So it seems that no such number can be used in C++, and speaking of
            >mathematical numbers, it makes perfect sense, but what is actually going on
            >"behing the curtains" in C++ since the compiled code can't discern between
            >+0 and -0 ?[/color]

            Read up on 2s complement. Even in a 1s complement implementation, the
            for an 8-bit binary number the bit pattern 11111111 will compare equal
            to 00000000, since 11111111 and 00000000 are both representations of
            0. For sign magnitude representations , 10000000 == 000000000 will hold
            true for the same reason.

            Tom

            Comment

            • MiniDisc_2k2

              #7
              Re: Signed int -0 ?

              It all comes down to how the computer represents those negative numbers. It
              does not exactly just reserve one bit as you say:

              decimal binary (8-bit)
              -3 11111101
              -2 11111110
              -1 11111111
              0 00000000
              1 00000001
              2 00000010
              3 00000011

              Thus you can see why there can be no -0. With each increase, the number
              increases by one. For further explanation, to convert a number to a
              negative, all you do is reverse all the bits (take the one's complement) and
              then add one (take the two's complement). Thus:

              If we start with 0: 00000000
              Take the one's complement: 11111111
              Take the two's complement: 00000000 (drop the 1 off from the end)

              You see we get the same number. Thus, no -0 exists.

              -- MiniDisc_2k2
              To reply, replace nospam.com with cox dot net.

              "Christian Stigen Larsen" <cslarsen@newsc ache.ntnu.no> wrote in message
              news:slrnbg8ce5 .fcg.cslarsen@g aupe.stud.ntnu. no...[color=blue]
              > A signed int reserves one bit to signify whether a number is positive or
              > negative. In light of this, a colleague asked me whether there existed an
              > int in C++ that was -0, a zero with the negative bit set. I was intrigued
              > by this, so I tried the following code:
              >
              > #include <stdio.h>
              >
              > int main(int, char**) {
              > int a(-0);
              > printf("a=%d\n" , a);
              > if ( a==0 ) printf("a==0\n" );
              > if ( a==-0 ) printf("a==-0\n");
              > return 0;
              > }
              >
              > The output is:
              >
              > a=0
              > a==0
              > a==-0
              >
              > So it seems that no such number can be used in C++, and speaking of
              > mathematical numbers, it makes perfect sense, but what is actually going[/color]
              on[color=blue]
              > "behing the curtains" in C++ since the compiled code can't discern between
              > +0 and -0 ?
              >
              > --
              > Christian Stigen Larsen -- http://sublevel3.org/~csl/[/color]


              Comment

              • Rolf Magnus

                #8
                Re: Signed int -0 ?

                Victor Bazarov wrote:
                [color=blue][color=green]
                >> Negative numbers are usually expressed as 2's complement, where e.g.
                >> an 8 bit number can represent values from -128 to +127, including
                >> onle one possible value for 0. It's not just one sign bit that is
                >> different.[/color]
                >
                > Both signed magnitude representation and 1's complement (which are,
                > IIRC, also allowed) have -0.[/color]

                That's why I used the word "usually" instead of "always".

                Comment

                • Suzanne Vogel

                  #9
                  Re: Signed int -0 ? [lib function for binary reps?]

                  For readers who skim, I'll start with a question (instead of burying it
                  below):
                  *** Is there a C++ library function that prints binary representations
                  of numbers?

                  Continuing. Thanks for the explanations. I was wondering yesterday
                  whether -0 had a different bit representation from 0. I thought how
                  terrible it would be if -0 *did* have a different bit representation
                  from 0, and NULL were defined as -0, and someone wrote an if-test that
                  relied on NULL being 0.

                  e.g.,
                  #define NULL -0 // redefine the NULL macro
                  ....
                  char* buf = (char*)malloc(s izeof(char)*N);
                  if (!buf) { // if NULL has a nonzero bit representation, this will fail!
                  exit(1);
                  }

                  I think we should rely on bit representations of things only when we
                  have to (e.g., low-level file processing) or when we're trying to make
                  programs run more efficiently (e.g., bit ops). And I stop here because I
                  haven't done much of either of these.

                  Below is a little program I wrote to print binary representations . Yeah,
                  most of us have probably written one of these. If a C++ library function
                  exists for this, I feel silly.

                  I thought that actually *printing* bit representations was necessary to
                  show that the bit representations of -0 and 0 differ, because C++ can do
                  typecasts behind your back (e.g., from -0 to 0? I didn't know and didn't
                  want to take a chance).

                  --Suzanne
                  ------------------------------------------------------------------------------------
                  // File: BitRepresentati onsMain.cpp

                  #include <iostream>

                  ///////////////////////////////////////////////////////////////////////////////
                  // TYPEDEFS AND CONSTANTS
                  ///////////////////////////////////////////////////////////////////////////////

                  const int NUM_BITS_PER_CH AR = 8;

                  ///////////////////////////////////////////////////////////////////////////////
                  // UTILITY FUNCTIONS
                  ///////////////////////////////////////////////////////////////////////////////

                  // Convert integer n to a null-terminated string of 0's and 1's
                  representing its
                  // binary representation.
                  template<class T>
                  char* toBinary(char* binary, T n)
                  {
                  // Advance the pointer all the way to the right.
                  long nbits = sizeof(T) * NUM_BITS_PER_CH AR;
                  binary += nbits;

                  // Append null.
                  *binary = '\0';
                  binary--;

                  // Write chars via the pointer.
                  for (int i=0; i < nbits; i++)
                  {
                  *binary = (n & 1)==1 ? '1' : '0';
                  n = n >> 1;
                  binary--;
                  }
                  binary++;
                  return binary;
                  }

                  ///////////////////////////////////////////////////////////////////////////////
                  // MAIN
                  ///////////////////////////////////////////////////////////////////////////////
                  int main(int argc, char** argv)
                  {
                  char* binary = (char*)malloc(s izeof(long) * NUM_BITS_PER_CH AR + 1);

                  std::cout << "-0:\t" << toBinary<int>(b inary, int(-0)) << "\n";
                  std::cout << "0:\t" << toBinary<int>(b inary, int(0)) << "\n";
                  std::cout << "-0:\t" << toBinary<long>( binary, long(-0)) << "\n";
                  std::cout << "0:\t" << toBinary<long>( binary, long(0)) << "\n";
                  std::cout << "-0:\t" << toBinary<char>( binary, char(-0)) << "\n";
                  std::cout << "0:\t" << toBinary<char>( binary, char(0)) << "\n";

                  for (int i=-3; i<=3; i++)
                  {
                  std::cout << i << ":\t" << toBinary<int>(b inary, int(i)) << "\n";
                  }

                  free(binary);

                  return EXIT_SUCCESS;
                  }

                  MiniDisc_2k2 wrote:[color=blue]
                  > It all comes down to how the computer represents those negative numbers. It
                  > does not exactly just reserve one bit as you say:[/color]

                  Comment

                  • Suzanne Vogel

                    #10
                    Re: Signed int -0 ? [lib function for binary reps?]

                    Thanks for the feedback.
                    [color=blue][color=green]
                    >>(e.g., from -0 to 0?[/color]
                    >
                    >
                    > Why do you think that would be a type conversion? Anyway, the compiler
                    > may keep the bits as they are and just treat 0 and -0 as equal.[/color]

                    *Suppose* (this is hypothetical) there were different representations of
                    0 and -0 for longs but not for ints.

                    Consider the following (made-up example):

                    if (0 == -0)... // possibly convert one of these

                    To compare 0 and -0, they must have the same type. So in *this* made-up
                    case, -0 would be a long and 0 would be an int, so 0 would be converted
                    (converted, not cast) to a long.

                    Similarly to the following (real example):

                    if (float(0.0) == double(0.0))... // convert float(0.0) to a double

                    ** Is this not right?
                    [color=blue]
                    >[color=green]
                    >>const int NUM_BITS_PER_CH AR = 8;[/color]
                    >
                    >
                    > Better use std::numeric_li mits<char>::dig its from the <limits> header or
                    > CHAR_BIT from <climits>.
                    >[/color]
                    Good idea.

                    ** Doesn't that just give the number of base-10 digits? If so, I guess I
                    could take the log base-2 of that to get the number of base-2 digits.

                    Suzanne

                    Comment

                    • Victor Bazarov

                      #11
                      Re: Signed int -0 ? [lib function for binary reps?]

                      "Suzanne Vogel" <suzanne_e_voge l@hotmail.com> wrote...[color=blue]
                      > Thanks for the feedback.
                      >[color=green][color=darkred]
                      > >>(e.g., from -0 to 0?[/color]
                      > >
                      > >
                      > > Why do you think that would be a type conversion? Anyway, the compiler
                      > > may keep the bits as they are and just treat 0 and -0 as equal.[/color]
                      >
                      > *Suppose* (this is hypothetical) there were different representations of
                      > 0 and -0 for longs but not for ints.
                      >
                      > Consider the following (made-up example):
                      >
                      > if (0 == -0)... // possibly convert one of these
                      >
                      > To compare 0 and -0, they must have the same type. So in *this* made-up
                      > case, -0 would be a long[/color]

                      No, it wouldn't. See the explanation below.
                      [color=blue]
                      > and 0 would be an int, so 0 would be converted
                      > (converted, not cast) to a long.
                      >
                      > Similarly to the following (real example):
                      >
                      > if (float(0.0) == double(0.0))... // convert float(0.0) to a double
                      >
                      > ** Is this not right?[/color]

                      No. Not according to the C++ grammar. In it the code "-0" is
                      not a literal but an expression. "0" is a literal. It has the
                      type 'int' and base 8 (because it begins with 0). It's an octal
                      literal, and since it can be represented by 'int', it is an 'int'.

                      Now, -0 is a constant expression which involves negation operator
                      and the integer expression. The result is calculated by the
                      compiler on the fly and is (you guessed it!) 0.

                      [color=blue][color=green][color=darkred]
                      > >>const int NUM_BITS_PER_CH AR = 8;[/color]
                      > >
                      > >
                      > > Better use std::numeric_li mits<char>::dig its from the <limits> header or
                      > > CHAR_BIT from <climits>.
                      > >[/color]
                      > Good idea.
                      >
                      > ** Doesn't that just give the number of base-10 digits?[/color]

                      No. For those there is std::numeric_li mits<char>::dig its10.
                      [color=blue]
                      > If so, I guess I
                      > could take the log base-2 of that to get the number of base-2 digits.[/color]

                      You don't need to.

                      Victor


                      Comment

                      • MiniDisc_2k2

                        #12
                        Re: Signed int -0 ? [lib function for binary reps?]


                        "Suzanne Vogel" <suzanne_e_voge l@hotmail.com> wrote in message
                        news:3f045eb5$1 _2@news.unc.edu ...[color=blue]
                        > For readers who skim, I'll start with a question (instead of burying it
                        > below):
                        > *** Is there a C++ library function that prints binary representations
                        > of numbers?[/color]

                        In a way, yes. You can ask C++ to convert the number to a string in binary
                        format and then print that string:

                        int a; // the variable you wish to represent in binary
                        format.
                        char* string = new char[50];
                        itoa(a, string, 2); // the 2 means binary
                        std::cout << string;
                        delete string;


                        Comment

                        • Victor Bazarov

                          #13
                          Re: Signed int -0 ? [lib function for binary reps?]

                          "MiniDisc_2 k2" <MattDelB@nospa m.com> wrote...[color=blue]
                          >
                          > "Suzanne Vogel" <suzanne_e_voge l@hotmail.com> wrote in message
                          > news:3f045eb5$1 _2@news.unc.edu ...[color=green]
                          > > For readers who skim, I'll start with a question (instead of burying it
                          > > below):
                          > > *** Is there a C++ library function that prints binary representations
                          > > of numbers?[/color]
                          >
                          > In a way, yes. You can ask C++ to convert the number to a string in binary
                          > format and then print that string:
                          >
                          > int a; // the variable you wish to represent in binary
                          > format.
                          > char* string = new char[50];
                          > itoa(a, string, 2); // the 2 means binary[/color]

                          Where did you dig out that function? Neither Standard C, nor
                          Standard C++ library has 'itoa'.
                          [color=blue]
                          > std::cout << string;
                          > delete string;
                          >
                          >[/color]


                          Comment

                          • Jack Klein

                            #14
                            Re: Signed int -0 ?

                            On Thu, 3 Jul 2003 13:38:13 +0000 (UTC), cslarsen@newsca che.ntnu.no
                            (Christian Stigen Larsen) wrote in comp.lang.c++:
                            [color=blue]
                            > A signed int reserves one bit to signify whether a number is positive or
                            > negative. In light of this, a colleague asked me whether there existed an
                            > int in C++ that was -0, a zero with the negative bit set. I was intrigued
                            > by this, so I tried the following code:
                            >
                            > #include <stdio.h>
                            >
                            > int main(int, char**) {
                            > int a(-0);
                            > printf("a=%d\n" , a);
                            > if ( a==0 ) printf("a==0\n" );
                            > if ( a==-0 ) printf("a==-0\n");
                            > return 0;
                            > }
                            >
                            > The output is:
                            >
                            > a=0
                            > a==0
                            > a==-0
                            >
                            > So it seems that no such number can be used in C++, and speaking of
                            > mathematical numbers, it makes perfect sense, but what is actually going on
                            > "behing the curtains" in C++ since the compiled code can't discern between
                            > +0 and -0 ?[/color]

                            There are three defined formats for the representation of negative
                            signed integer values. Two of them have the physical possibility of
                            representing -0, one does not. Of the two that can physically
                            represent -0, that might actually be a valid value, or it might be a
                            trap value that causes undefined behavior.

                            On implementations that support -0, if you could actually find one, it
                            is required to compare equal to ordinary 0.

                            --
                            Jack Klein
                            Home: http://JK-Technology.Com
                            FAQs for
                            comp.lang.c http://www.eskimo.com/~scs/C-faq/top.html
                            comp.lang.c++ http://www.parashift.com/c++-faq-lite/
                            alt.comp.lang.l earn.c-c++ ftp://snurse-l.org/pub/acllc-c++/faq

                            Comment

                            • Ron Natalie

                              #15
                              Re: Signed int -0 ?


                              "Jack Klein" <jackklein@spam cop.net> wrote in message news:2c0agv8eek oificl7rmqab2tp arvn5scsr@4ax.c om...
                              [color=blue]
                              > There are three defined formats for the representation of negative
                              > signed integer values.[/color]

                              Only in C99.


                              Comment

                              Working...