c++ - Unsigned vs signed range guarantees -
i've spent time poring on standard references, i've not been able find answer following:
- is technically guaranteed c/c++ standard that, given signed integral type s , unsigned counterpart u, absolute value of each possible s less or equal maximum value of u?
the closest i've gotten section 6.2.6.2 of c99 standard (the wording of c++ more arcane me, assume equivalent on this):
for signed integer types, bits of object representation shall divided 3 groups: value bits, padding bits, , sign bit. (...) each bit value bit shall have same value same bit in object representation of corresponding unsigned type (if there m value bits in signed type , nin unsigned type, mâ¤n).
so, in hypothetical 4-bit signed/unsigned integer types, preventing unsigned type have 1 padding bit , 3 value bits, , signed type having 3 value bits , 1 sign bit? in such case range of unsigned [0,7] , signed [-8,7] (assuming two's complement).
in case curious, i'm relying @ moment on technique extracting absolute value of negative integer consisting of first cast unsigned counterpart, , application of unary minus operator (so instance -3 becomes 4 via cast , 3 via unary minus). break on example above -8, not represented in unsigned type.
edit: replies below keith , potatoswatter. now, last point of doubt on meaning of "subrange" in wording of standard. if means strictly "less-than" inclusion, example above , keith's below not standard-compliant. if subrange intended potentially whole range of unsigned, are.
for c, answer no, there no such guarantee.
i'll discuss types int
, unsigned int
; applies equally corresponding pair of signed , unsigned types (other char
, unsigned char
, neither of can have padding bits).
the standard, in section quoted, implicitly guarantees uint_max >= int_max
, means every non-negative int
value can represented unsigned int
.
but following legal (i'll use **
denote exponentiation):
char_bit == 8 sizeof (int) == 4 sizeof (unsigned int) == 4 int_min = -2**31 int_max = +2**31-1 uint_max = +2**31-1
this implies int
has 1 sign bit (as must) , 31 value bits, ordinary 2's-complement representation, , unsigned int
has 31 value bits , 1 padding bit. unsigned int
representations padding bit set might either trap representations, or representations of values padding bit unset.
this might appropriate machine support 2's-complement signed arithmetic, poor support unsigned arithmetic.
given these characteristics, -int_min
(the mathematical value) outside range of unsigned int
.
on other hand, doubt there modern systems this. padding bits permitted standard, rare, , don't expect them become more common.
you might consider adding this:
#if -int_min > uint_max #error "nope" #endif
to source, compile if can want. (you should think of better error message "nope"
, of course.)
Comments
Post a Comment