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

Popular posts from this blog

javascript - backbone.js Collection.add() doesn't `construct` (`initialize`) an object -

php - Get uncommon values from two or more arrays -

Adding duplicate array rows in Php -