Why is the sign different after subtracting unsigned and signed?

• A+
Category：Languages
unsigned int t = 10; int d = 16; float c = t - d; int e = t - d;

Why is the value of c positive but e negative?

Let's start by analysing the result of t - d.

t is an unsigned int while d is an int, so to do arithmetic on them, the value of d is converted to an unsigned int (C++ rules say unsigned gets preference here). So we get 10u - 16u, which (assuming 32-bit int) wraps around to 4294967290u.

This value is then converted to float in the first declaration, and to int in the second one.

Assuming the typical implementation of float (32-bit single-precision IEEE), its highest representable value is roughly 1e38, so 4294967290u is well within that range. There will be rounding errors, but the conversion to float won't overflow.

For int, the situation's different. 4294967290u is too big to fit into an int, so wrap-around happens and we arrive back at the value -6. Note that such wrap-around is not guaranteed by the standard: the resulting value in this case is implementation-defined(1), which means it's up to the compiler what the result value is, but it must be documented.

(1) C++17 (N4659), [conv.integral] 7.8/3:

If the destination type is signed, the value is unchanged if it can be represented in the destination type; otherwise, the value is implementation-defined.