62

I'm just amazed to know that I can't convert signed to unsigned int by casting!

int i = -62;
unsigned int j = (unsigned int)i;

I thought I already knew this since I started to use casts, but I can't do it!

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
John
  • 631
  • 1
  • 6
  • 4
  • 14
    what would you logically expect this cast to do? – tenfour Feb 12 '11 at 00:17
  • My bad guys, But I appreciate the explanation. I was trying to convert signed char -62 to unsigned int and expecting to get a value of 194 (x.x) – John Feb 12 '11 at 00:43
  • 4
    Um... Casting? Conversions between integer types do not require casts in C++. They are *standard conversions*, and they are performed implicitly. In your case you could simply do `unsigned int j = i;` for exactly the same effect. – AnT stands with Russia Jan 24 '17 at 00:37
  • 5
    Your code compiles just fine ([live on godbolt](https://godbolt.org/z/WRWFrs)). Could you edit the question so that it does not imply, that it does not compile? It's misleading. – Dr. Gut Apr 24 '20 at 12:40
  • A litle nitpicking, but for the newbies out there, in C++ you should not use c casts `(unsigned int)i` any more. use `static_cast(i)`. See https://stackoverflow.com/a/103868/1614903 for elaboration. – Holger Böhnke May 13 '23 at 00:00

7 Answers7

65

You can convert an int to an unsigned int. The conversion is valid and well-defined.

Since the value is negative, UINT_MAX + 1 is added to it so that the value is a valid unsigned quantity. (Technically, 2N is added to it, where N is the number of bits used to represent the unsigned type.)

In this case, since int on your platform has a width of 32 bits, 62 is subtracted from 232, yielding 4,294,967,234.

James McNellis
  • 348,265
  • 75
  • 913
  • 977
  • 6
    @SIFE the integer being converted is -62... so when you add UINT_MAX (which is 2^32) to it, it becomes a subtraction of 62. – Luke Apr 12 '13 at 10:14
49

Edit: As has been noted in the other answers, the standard actually guarantees that "the resulting value is the least unsigned integer congruent to the source integer (modulo 2n where n is the number of bits used to represent the unsigned type)". So even if your platform did not store signed ints as two's complement, the behavior would be the same.


Apparently your signed integer -62 is stored in two's complement (Wikipedia) on your platform:

62 as a 32-bit integer written in binary is

0000 0000 0000 0000 0000 0000 0011 1110

To compute the two's complement (for storing -62), first invert all the bits

1111 1111 1111 1111 1111 1111 1100 0001

then add one

1111 1111 1111 1111 1111 1111 1100 0010

And if you interpret this as an unsigned 32-bit integer (as your computer will do if you cast it), you'll end up with 4294967234 :-)

puzzle
  • 6,071
  • 1
  • 25
  • 30
9

This conversion is well defined and will yield the value UINT_MAX - 61. On a platform where unsigned int is a 32-bit type (most common platforms, these days), this is precisely the value that others are reporting. Other values are possible, however.

The actual language in the standard is

If the destination type is unsigned, the resulting value is the least unsigned integer congruent to the source integer (modulo 2^n where n is the number of bits used to represent the unsigned type).

Stephen Canon
  • 103,815
  • 19
  • 183
  • 269
  • 1
    As the standard has a clear definition.Why other values are still possible? – John May 16 '21 at 02:53
  • The value is different for different sizes of integers. That's why the standard talks about "congruent" and "number of bits". – soulsource Nov 29 '22 at 15:16
4

i=-62 . If you want to convert it to a unsigned representation. It would be 4294967234 for a 32 bit integer. A simple way would be to

num=-62
unsigned int n;
n = num
cout<<n;

4294967234

Himanshu Poddar
  • 7,112
  • 10
  • 47
  • 93
3

with a little help of math

#include <math.h>
int main(){
  int a = -1;
  unsigned int b;
  b = abs(a);
}
diezsiete
  • 2,034
  • 1
  • 16
  • 13
  • 1
    @chad: There's absolutely no difference in specification of signed -> unsigned conversion between C and C++. It works identically in both languages. – AnT stands with Russia Jan 24 '17 at 00:39
  • 2
    Oh man, I accidentally just deleted my comment. Sorry! It originally said something along the lines of this wouldn't work because the difference in twos compliment representation. I have no idea what I was thinking when I wrote this, you're absolutely correct. – chad Apr 13 '17 at 20:26
3

Since we know that i is an int, you can just go ahead and unsigneding it!

This would do the trick:

int i = -62;
unsigned int j = unsigned(i);
Clijsters
  • 4,031
  • 1
  • 27
  • 37
Halllloooo
  • 51
  • 1
2

From c++17, one can use make_unsigned_t

auto uint_variable = std::make_unsigned_t<int>(-62); //4294967234
Pavan Chandaka
  • 11,671
  • 5
  • 26
  • 34