有符号C ++整数的非负范围是否至少与负范围一样大?

时间:2014-03-05 17:00:15

标签: c++ signed twos-complement

C ++标准是否要求标准有符号整数类型的非负范围至少与负范围一样大?

编辑:请注意我在这里指的是非负范围,而不是范围,这显然小于非负数范围。

编辑:如果我们假设C ++ 11,答案是"是"。请参阅下面的说明。从C ++ 03的角度来看,答案可能是" No"。

同样的问题可以提出如下:标准是否保证a - b的结果在标准有符号整数类型T中可表示,假设a和{{1}类型为b否定值,T是什么?

我知道该标准允许两个补充,一个'补数和负值的符号幅度表示(见C ++ 11第3.9.1节[basic.fundamental]第7段),但我不确定它是否要求使用这三种表示中的一种。可能不是。

如果我们假设这三种表示中的一种,并且我们假设没有"假的"对两个范围中的任何一个(负的和非负的)的限制,那么非负范围确实至少与负范围一样大。实际上,使用两个补码时,两个范围的大小将相等,而对于另外两个表示,非负范围的大小将比负数的大小大一。

然而,即使我们假设其中一个提到的表示形式,也不足以保证任何一个范围的大小。

我在这里寻求的是一个明确提供所需保证的部分(或部分部分)。

任何帮助将不胜感激。


请注意,类似下面的内容就足够了:"存储槽中的每一位"整数的一个,只有以下函数之一:

  • 未使用的
  • 符号位(专用或混合符号/值位)
  • 值位(参与值)

我有一个模糊的记忆,C99在这些方面说了些什么。任何人都知道这件事吗?


好的,C99(TC3)确实在6.2.6.2和#34;整数类型"中提供了必要的保证。第2段:

  

对于有符号整数类型,对象表示的位应分为三组:值位,填充位和符号位。不需要任何填充位;应该只有一个符号位。作为值位的每个位应具有与相应无符号类型的对象表示中的相同位相同的值(如果有符号类型中有M个值位且无符号类型中有N,则M≤N)。如果符号位为零,则不应影响结果值。如果符号位为1,则应以下列方式之一修改该值:

     
      
  • 符号位0的对应值被否定(符号和幅度);
  •   
  • 符号位的值为 - (2 N )(二进制补码);
  •   
  • 符号位的值为 - (2 N - 1)(补码)。
  •   
     

其中哪一个适用于实现定义,符号位1和所有值位0(前两个)的值,或符号位和所有值位1(对于补码)是否为陷阱表示或正常值。在符号和幅度以及1的补码的情况下,如果该表示是正常值,则称为负零。

有人可以确认C99的这一部分也是C ++ 11的绑定部分吗?


我仔细研究了C99和C ++ 11标准,很明显C99第6.2.6.2节第2段中的保证也在C ++ 11中具有约束力。

C89 / C90没有提供相同的保证,所以我们确实需要C99,这意味着我们确实需要C ++ 11。

总之,C ++ 11(和C99)提供了以下保证:

  1. 基本有符号整数类型(标准+扩展)中的负值必须使用以下三种表示之一来表示:两个补码,一个'补充或签署量级。

  2. 非负范围的大小大于或等于所有基本有符号整数类型的负范围大小(标准+扩展)。

  3. 第二项保证可以重述如下:

    a ≥ b

    表示任何基本签名整数类型-1 ≤ min<T> + max<T> ≤ 0 (标准+扩展),其中Tmin<T>分别是max<T>std::numeric_limits<T>::min()的缩写。

    另外,如果我们假设std::numeric_limits<T>::max()a是相同或不同基本有符号整数类型(标准或扩展)的值,则b表示良好只要a - bdecltype(a - b)既是否定的,也可以是非负的,都会在a中定义和表示。

1 个答案:

答案 0 :(得分:3)

虽然我可能缺少关键段落,但标准似乎并没有强制要求这样做。我们所知道的基本有符号整数类型是3.9.1 / 2:

  

有五种标准的有符号整数类型:“signed char”,“short”   int“,”int“,”long int“和”long long int“。在此列表中,每种类型   提供至少与列表中前面的存储一样多的存储空间。

在3.9.1 / 7中:

  

类型bool,char,char16_t,char32_t,wchar_t,以及签名和   无符号整数类型统称为整数类型.48 A   整数类型的同义词是整数类型。的陈述   整数类型应使用纯二进制计数定义值   系统

这些段落似乎都没有说明各自的正面和负面范围。即使考虑到我无法设想不符合您需求的二进制表示。