Thread: Converting signed to unsigned

1. 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. Ah actually disregard. static_cast<> would do it. I thought it was technically undefined but it isn't! 3. Originally Posted by cyberfish 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). 4. 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 Tags for this Thread

int8_t, larger, type, types, work 