Converting an integer to a signed type when the source value can't be represented in the destination type is according to cppreference
- implementation-defined (until C 20)
- the unique value of the destination type equal to the source value modulo 2^n where n is the number of bits used to represent the destination type (since C 20)
Also specified in GCC implementation-defined behavior, there is
For conversion to a type of width N, the value is reduced modulo 2^N to be within range of the type; no signal is raised.
I guess there are saying the same thing. My question is isn't the reduced/moduloed result still maybe out of range of the destination signed type? Say signed char c = 255
, 255 modulo 2^8 is still 255, unchanged. How does this moduloed result fit into the destination type?
This answer shows a method to first invert the value and add 1, then prepend a signed bit. I'm not sure if that's what actually have been done.
What's the correct/standard way to interpret the emphasized part?
CodePudding user response:
Neither of these quotes are meant to say that the original value is taken, the modulo operation applied, and the result used as result of the conversion.
Instead they are meant to say that out of all values v
representable in the destination type, the (unique) one for which the mathematical equality
s m * 2^n = v
holds for some integer m
, with s
the source value, is chosen. It is said that s
and v
are congruent modulo 2^n
if they satisfy this condition or sometimes also that they are equal modulo 2^n
.
For s = 255
with signed target of width 8
, 255
is not representable, but -1
is and v = -1
satisfies the equation with m = -1
.
CodePudding user response:
Say signed char = 255U, 255 modulo 2^8 is still 255
255 isn't within range of the type (of 8 bit signed integer).
One way to re-phrase the rule is that the converted result will be congruent with the unrepresentable result modulo 2^n.
-513, -257, -1, 255, 511 are all congruent modulo 256. Of the congruent numbers, only -1 is within the representable range of the signed type.