Thread: Converting signed to unsigned

  1. #1
    Registered User
    Join Date
    Dec 2006
    Location
    Canada
    Posts
    3,226

    Converting signed to unsigned

    Is there a way to store the absolute value of a signed value into an unsigned type of the same size? I don't want to use a larger type, because this is a template function that will need to work with all integral types (including the largest type).

    For example, this doesn't work because 128 would overflow int8_t. It would work if we allow automatic promotions, but that's not an option for larger types.
    Code:
    int8_t x = -128;
    int8_t neg_x = -x;
    uint8_t abs_x = neg_x;
    Thanks

  2. #2
    Registered User
    Join Date
    Dec 2006
    Location
    Canada
    Posts
    3,226
    Ah actually disregard. static_cast<> would do it. I thought it was technically undefined but it isn't!

  3. #3
    Registered User
    Join Date
    Feb 2019
    Posts
    550
    Quote Originally Posted by cyberfish View Post
    Is there a way to store the absolute value of a signed value into an unsigned type of the same size?...
    For example, this doesn't work because 128 would overflow int8_t...
    Yep, use stdlib.h abs() function:
    Code:
    #include <stdlib.h>
    #include <stdio.h>
    #include <stdint.h>
    
    int main( void )
    {
      int8_t x = -128;
      uint8_t y;
    
      // since uint8_t has more precision (8 bits) than int8_t (7 bits), this is safe:
      y = abs(x);
    
      printf( "abs(%hhd) == %hhu\n", x, y );
    
      // this will overflow!
      x = abs(y);
    
      printf( "abs(%hhu) == %hhd\n", y, x );
    }
    $ cc -o test test.c
    $ ./test
    abs(-128) == 128
    abs(128) == -128
    If your type has precision bigger than 31 bits (int) use labs() (long) or llabs() (long long).
    Last edited by flp1969; 05-18-2019 at 06:33 AM.

  4. #4
    Registered User
    Join Date
    Dec 2006
    Location
    Canada
    Posts
    3,226
    This works because of the same thing I just realized in my own reply above - the standard guarantees that casting a signed type to unsigned preserves the bit pattern in 2's complement (and architectures not using 2's complement also have to emulate this behaviour).

    So
    Code:
    int8_t x = -128;
    x *= -1;
    uint8_t y = static_cast<uint8_t>(x);
    works (in my case I know the number must be negative).

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Signed and unsigned
    By ncode in forum C Programming
    Replies: 3
    Last Post: 09-02-2011, 08:59 PM
  2. Unsigned vs. Signed?
    By Programmer_P in forum C++ Programming
    Replies: 4
    Last Post: 12-22-2009, 01:15 PM
  3. signed or unsigned?
    By ulillillia in forum C Programming
    Replies: 7
    Last Post: 05-08-2007, 01:06 AM
  4. signed/unsigned int
    By X PaYnE X in forum C Programming
    Replies: 3
    Last Post: 06-10-2004, 10:58 AM
  5. signed vs unsigned
    By char in forum C Programming
    Replies: 1
    Last Post: 04-24-2002, 01:10 PM

Tags for this Thread