枚举范围混乱

发布于 2024-10-01 15:43:17 字数 283 浏览 0 评论 0原文

如何找到枚举的范围? 我有两个版本,当最低值为负数时,它们的表述不同。Stroustrup 说的是,

 enum e3 { min = -10 , max = 1000000 }; // range -1048576:1048575

但是 C++ Primer Plus 第五版说

例如,如果最小的枚举数是 -6,则下一个 2 的幂[乘负号]是 -8,因此下限是 -7

我很困惑哪个是正确的?

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:1048575

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 ?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

云醉月微眠 2024-10-08 15:43:17

我相信两者都是正确的(不过,请参阅下面的 Primer 定义),具体取决于您想要的兼容性。正式的定义是

对于 e min 是最小枚举器且 e max 是最大枚举器的枚举,枚举的值是 b min 到 b max 范围内基础类型的值,其中 b min 和 b max 分别是,可以存储 e min 和 e max 的最小位域的最小值和最大值。

对于负数,问题是我们使用什么表示形式。它的脚注说

在二进制补码机器上,b
max 是大于或等于 max (abs(e min ) − 1 ,abs(e max ) ) 形式的最小值
2M-1;如果 e 为非负数,则 b 为零,否则为 − (b + 1 )。

如果您假设符号大小或补码,则示例枚举的范围为 -1048575:1048575。对于二进制补码,您会在负数范围内多得到一个。 Primer 的定义缺少最大枚举值,所以我不确定它是如何达到下限 -7 的。如果您想与其他实现最大程度地兼容,我会选择 -1048575:1048575

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.

说谎友 2024-10-08 15:43:17

C++ 标准规定 (§[dcl.enum]/7):

否则,对于 emin 是最小枚举数、emax 是最大枚举数的枚举,枚举的值是 bminbmin 范围内的值,定义如下:< /p>

  • K 为 1,表示二进制补码......
  • bmax 是大于或等于 max(|emin| − < em>K, |emax|) 且等于 2M − 1,其中M是一个非负整数。
  • 如果 emin 为非负且 -(b< sub>max + K)否则。

例如,在第一种情况下,

  • emin = -10,emax = 1000000
  • 因此 bmax ≥ max(10 − 1, 1000000) = 1000000
  • bmax 必须采用 2< 形式em>M − 1,所以我们使用 M = 20 ⇒ bmax = 1048575
  • e min 为负数,因此 bmin = −(1048575 + 1) = −1048576。

在第二种情况下,

  • emin = -6,emax = 未指定,
  • 因此bmax ≥ max(6 − 1, 未指定) = 5 或以上
  • 如果未指定确实小于 5,则 bmax 必须为 7,bmin 为 -8。
  • 然而,如果该未指定的数字>7,则范围将更宽。

因此,C++ Primer 是不正确的,因为它忽略了上限的影响。

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.

晨与橙与城 2024-10-08 15:43:17

它们是完全相同的陈述,只是使用不同的尺度。要存储数字 1000000,您需要 20 位,因此您的范围是 -1048576 到 +1048575。要存储 -6,您需要 3 位,因此这 3 位可以存储的范围是 -8 到 +7。

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文