A question about taking the absolute value of an integer

Discussion in 'C Programming' started by Chad, Jan 5, 2008.

  1. Chad

    Chad Guest

    I really don't understand how something like..

    #define abs(x) (((x) < 0) ? -(x) : (x))

    could cause a possible overflow.
     
    Chad, Jan 5, 2008
    #1
    1. Advertising

  2. In article <>,
    Chad <> wrote:

    >I really don't understand how something like..


    >#define abs(x) (((x) < 0) ? -(x) : (x))


    >could cause a possible overflow.


    e.g., INT_MIN might be -32768.
    -(-32768) ---> 32768 but INT_MAX might be 32767

    This is an issue in any implementation that uses twos complement
    (unless it reserves the minimum integral value for some reason,
    which would be quite unusual.)

    It might help to look at the binary values involved.
    On a system with a two-byte unsigned short, for example,
    SHORT_MIN would be 0x8000 . To take the negative,
    toggle each bit and then add 1 to the result. Toggling each
    bit of 0x8000 would be 0x7FFF; add 1 and you get 0x8000 which
    is the original value back again.
    --
    "I was very young in those days, but I was also rather dim."
    -- Christopher Priest
     
    Walter Roberson, Jan 5, 2008
    #2
    1. Advertising

  3. Chad

    Eric Sosman Guest

    Chad wrote:
    > I really don't understand how something like..
    >
    > #define abs(x) (((x) < 0) ? -(x) : (x))
    >
    > could cause a possible overflow.


    Find a machine where INT_MIN + INT_MAX == -1 (that's
    nearly every machine nowadays) and evaluate abs(INT_MIN).

    --
    Eric Sosman
    lid
     
    Eric Sosman, Jan 5, 2008
    #3
  4. Chad

    Chad Guest

    On Jan 5, 1:10 pm, Eric Sosman <> wrote:
    > Chad wrote:
    > > I really don't understand how something like..

    >
    > > #define abs(x) (((x) < 0) ? -(x) : (x))

    >
    > > could cause a possible overflow.

    >
    > Find a machine where INT_MIN + INT_MAX == -1 (that's
    > nearly every machine nowadays) and evaluate abs(INT_MIN).
    >
    > --
    > Eric Sosman
    >



    % more abs.c
    #include <stdio.h>
    #include <stdlib.h>
    #include <limits.h>

    int main(void)
    {
    printf("%u\n",abs(INT_MIN));
    return 0;
    }

    % ./abs
    2147483648
     
    Chad, Jan 5, 2008
    #4
  5. Chad

    Coos Haak Guest

    Op Sat, 5 Jan 2008 13:24:09 -0800 (PST) schreef Chad:

    > On Jan 5, 1:10 pm, Eric Sosman <> wrote:
    >> Chad wrote:
    >>> I really don't understand how something like..

    >>
    >>> #define abs(x) (((x) < 0) ? -(x) : (x))

    >>
    >>> could cause a possible overflow.

    >>
    >> Find a machine where INT_MIN + INT_MAX == -1 (that's
    >> nearly every machine nowadays) and evaluate abs(INT_MIN).
    >>
    >> --
    >> Eric Sosman
    >>

    >
    >
    > % more abs.c
    > #include <stdio.h>
    > #include <stdlib.h>
    > #include <limits.h>
    >
    > int main(void)
    > {
    > printf("%u\n",abs(INT_MIN));
    > return 0;
    > }
    >
    > % ./abs
    > 2147483648


    Try printf("%n\n" ....
    the result will be a negative number. And an absolute value shall be
    positive ;-(
    --
    Coos
     
    Coos Haak, Jan 5, 2008
    #5
  6. Chad

    Eric Sosman Guest

    Chad wrote:
    > On Jan 5, 1:10 pm, Eric Sosman <> wrote:
    >> Chad wrote:
    >>> I really don't understand how something like..
    >>> #define abs(x) (((x) < 0) ? -(x) : (x))
    >>> could cause a possible overflow.

    >> Find a machine where INT_MIN + INT_MAX == -1 (that's
    >> nearly every machine nowadays) and evaluate abs(INT_MIN).

    >
    > % more abs.c
    > #include <stdio.h>
    > #include <stdlib.h>
    > #include <limits.h>
    >
    > int main(void)
    > {
    > printf("%u\n",abs(INT_MIN));
    > return 0;
    > }
    >
    > % ./abs
    > 2147483648


    ... which proves -- what, exactly? That two instances
    of undefined behavior (one for the overflow, one for the
    argument mismatch in printf) always produce a correct result?

    Try printing the value of INT_MAX for comparison. Or
    try checking the sign of abs(INT_MIN):

    printf ("|%d| is %s\n", INT_MIN,
    abs(INT_MIN) < 0 ? "negative" : "non-negative");

    Here's the point that's sometimes overlooked: "Undefined
    behavior" does not mean "The program will crash." It means
    the program *may* crash -- or may do something less violent
    but still unwelcome, or may do something apparently benign.
    It may even do what you expected, on some machines under some
    circumstances and for some values of "what you expected."
    For example, I expect a certain outcome from the printf
    above; the C language does not guarantee the outcome I expect,
    but I expect it anyhow. Does that mean it would be a good
    idea to *rely* on the expected-but-not-guaranteed behavior?
    No, it certainly does not.

    --
    Eric Sosman
    lid
     
    Eric Sosman, Jan 5, 2008
    #6
  7. In article <>,
    Chad <> wrote:

    >% more abs.c
    >#include <stdio.h>
    >#include <stdlib.h>
    >#include <limits.h>
    >
    >int main(void)
    >{
    > printf("%u\n",abs(INT_MIN));
    > return 0;
    >}
    >
    >% ./abs
    >2147483648


    Perhaps you will see your mistake if you change the printf line
    to:

    printf("%u %u\n",INT_MIN, abs(INT_MIN));

    -- Richard
    --
    :wq
     
    Richard Tobin, Jan 5, 2008
    #7
  8. Chad

    Chad Guest

    On Jan 5, 2:29 pm, Eric Sosman <> wrote:
    > Chad wrote:
    > > On Jan 5, 1:10 pm, Eric Sosman <> wrote:
    > >> Chad wrote:
    > >>> I really don't understand how something like..
    > >>> #define abs(x) (((x) < 0) ? -(x) : (x))
    > >>> could cause a possible overflow.
    > >> Find a machine where INT_MIN + INT_MAX == -1 (that's
    > >> nearly every machine nowadays) and evaluate abs(INT_MIN).

    >
    > > % more abs.c
    > > #include <stdio.h>
    > > #include <stdlib.h>
    > > #include <limits.h>

    >
    > > int main(void)
    > > {
    > > printf("%u\n",abs(INT_MIN));
    > > return 0;
    > > }

    >
    > > % ./abs
    > > 2147483648

    >
    > ... which proves -- what, exactly? That two instances
    > of undefined behavior (one for the overflow, one for the
    > argument mismatch in printf) always produce a correct result?
    >
    > Try printing the value of INT_MAX for comparison. Or
    > try checking the sign of abs(INT_MIN):
    >
    > printf ("|%d| is %s\n", INT_MIN,
    > abs(INT_MIN) < 0 ? "negative" : "non-negative");
    >
    > Here's the point that's sometimes overlooked: "Undefined
    > behavior" does not mean "The program will crash." It means
    > the program *may* crash -- or may do something less violent
    > but still unwelcome, or may do something apparently benign.
    > It may even do what you expected, on some machines under some
    > circumstances and for some values of "what you expected."
    > For example, I expect a certain outcome from the printf
    > above; the C language does not guarantee the outcome I expect,
    > but I expect it anyhow. Does that mean it would be a good
    > idea to *rely* on the expected-but-not-guaranteed behavior?
    > No, it certainly does not.
    >
    > --
    > Eric Sosman
    >



    When I posted the code, I was missing the bigger picture at the time.
    After sitting and thinking about the whole thing, I finally "got it".
     
    Chad, Jan 6, 2008
    #8
  9. On Sat, 5 Jan 2008 22:33:40 +0100, Coos Haak <>
    wrote:

    > Op Sat, 5 Jan 2008 13:24:09 -0800 (PST) schreef Chad:


    > > printf("%u\n",abs(INT_MIN));

    <snip: appears to work>

    > Try printf("%n\n" ....
    > the result will be a negative number. And an absolute value shall be
    > positive ;-(


    %d or %i. %n is something quite different, and wrong here.

    - formerly david.thompson1 || achar(64) || worldnet.att.net
     
    David Thompson, Jan 22, 2008
    #9
  10. Chad

    Coos Haak Guest

    Op Tue, 22 Jan 2008 05:22:40 GMT schreef David Thompson:

    > On Sat, 5 Jan 2008 22:33:40 +0100, Coos Haak <>
    > wrote:
    >
    >> Op Sat, 5 Jan 2008 13:24:09 -0800 (PST) schreef Chad:

    >
    >>> printf("%u\n",abs(INT_MIN));

    > <snip: appears to work>
    >
    >> Try printf("%n\n" ....
    >> the result will be a negative number. And an absolute value shall be
    >> positive ;-(

    >
    > %d or %i. %n is something quite different, and wrong here.
    >


    Absolutely, thanks.
    --
    Coos
     
    Coos Haak, Jan 22, 2008
    #10
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Replies:
    16
    Views:
    504
    Neil Kurzman
    Apr 7, 2005
  2. Robben
    Replies:
    14
    Views:
    566
    Old Wolf
    Dec 27, 2005
  3. John B. Matthews
    Replies:
    73
    Views:
    4,470
    John B. Matthews
    Nov 9, 2009
  4. Jim Cain
    Replies:
    1
    Views:
    209
    Yukihiro Matsumoto
    Jul 18, 2003
  5. James Byrne
    Replies:
    3
    Views:
    565
    James Byrne
    Sep 14, 2010
Loading...

Share This Page