Confusion in range of enums
How to find the range of enums ? I have got two versions which state it differently when the lowest value is negative.Stroustrup says that for
enum e3 { min = -10 , max = 1000000 }; // range -1048576:104857开发者_StackOverflow社区5
but C++ Primer Plus 5th edition says
for eg if the smallest enumerator is -6, the next power of two [times a minus sign] is -8, and thus the lower limit is -7
I am confused which is correct ?
I believe both are correct (see below for Primer's definition, though), depending on how compatible you want to are. The formal definition is
For an enumeration where e min is the smallest enumerator and e max is the largest, the values of the enumeration are the values of the underlying type in the range b min to b max , where b min and b max are, respectively, the smallest and largest values of the smallest bit-field that can store e min and e max .
For negative numbers, the question is what representation we use. The footnote to it says
On a two’s-complement machine, b max is the smallest value greater than or equal to max (abs(e min ) − 1 ,abs(e max ) ) of the form 2 M − 1; b is zero if e is non-negative and − (b + 1 ) otherwise.
If you assume sign magnitude or one's complement then the example enumeration's range is -1048575:1048575
. For two's complement you get one more in the negative range. Primer's definiton lacks the maximum enumerator value, so I'm not sure how it comes to lower limit -7
. If you want to be maximum compatible with other implementations, I would go with -1048575:1048575
.
The C++ standard says (§[dcl.enum]/7):
Otherwise, for an enumeration where emin is the smallest enumerator and emax is the largest, the values of the enumeration are the values in the range bmin to bmin, defined as follows:
- Let K be 1 for a two’s complement representation ....
- bmax is the smallest value greater than or equal to max(|emin| − K, |emax|) and equal to 2M − 1, where M is a non-negative integer.
- bmin is zero if emin is non-negative and −(bmax + K) otherwise.
For example, in the first case,
- emin = -10, emax = 1000000
- Thus bmax ≥ max(10 − 1, 1000000) = 1000000
- bmax must be of the form 2M − 1, so we use M = 20 ⇒ bmax = 1048575
- emin is negative, so bmin = −(1048575 + 1) = −1048576.
In the second case,
- emin = -6, emax = unspecified
- Thus bmax ≥ max(6 − 1, unspecified) = 5 or more
- If that unspecified is indeed less than 5, then bmax must be 7, and bmin is -8.
- However, if that unspecified number is >7, then the range will be wider.
Therefore, C++ Primer is incorrect, since it ignores the effect of the upper bound.
They are exactly same statements, just using different scales. To store number 1000000 you need 20 bits, so your range is -1048576 to +1048575. To store -6 you need 3 bits, so the range you can store in those 3 bits is -8 to +7.
精彩评论