首页 文章

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

提问于
浏览
4

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

编辑:请注意,我指的是 non-negative 范围,而不是 positive 范围,显然比 non-negative 范围小 .

编辑:如果我们假设C 11,答案是“是” . 请参阅下面的说明 . 从C 03的角度来看,答案可能是“不” .

同样的问题可以提出如下:标准是否保证 a - b 的结果在标准有符号整数类型 T 中可表示,假设 ab 都是 Tnegative 值,并且 a ≥ b

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

如果我们假设这三种表示中的一种,并且我们假设两个范围中的任何一个(负的和非负的)都没有“假的”限制,那么非负范围确实至少为很重要的是消极的 . 实际上,对于两个补码,两个范围的大小将相等,并且对于另外两个表示,非负范围的大小将比负数的大小大一 .

但是,即使我们假设其中一个提到的表示,也不足以保证任何一个范围的大小 .

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

任何帮助将不胜感激 .


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

  • 未使用

  • 符号位(专用或混合符号/值位)

  • 值位(参与值)

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


好的,C99(带TC3)确实在第6.2.6.2节“整数类型”第2节中提供了必要的保证:

对于有符号整数类型,对象表示的位应分为三组:值位,填充位和符号位 . 不需要任何填充位;应该只有一个符号位 . 作为值位的每个位应具有与相应无符号类型的对象表示中的相同位相同的值(如果有符号类型中有M个值位且无符号类型中有N,则M≤N) . 如果符号位为零,则不应影响结果值 . 如果符号位为1,则应以下列方式之一修改该值:符号位0的相应值被否定(符号和幅度);符号位的值为 - (2N)(二进制补码);符号位的值为 - (2N - 1)(1'补码) . 这些适用中的哪一个是实现定义的,将符号位1和所有值位0(对于前两个),或者符号位和所有值位1(对于1'补码)的值是否是陷阱表示或正常值 . 在符号和幅度以及1'补码的情况下,如果该表示是正常值,则称为负零 .

有人可以确认C99的这一部分也是C 11的约束部分吗?


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

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

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

  • 基本有符号整数类型中的负值(标准扩展) must 使用以下三种表示形式之一表示:两个's complement, ones'补码或符号幅度 .

  • non-negative 范围的大小 one 大于或等于所有基本有符号整数类型(标准扩展)的负范围大小 .

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

-1 ≤ min<T> + max<T> ≤ 0

对于任何基本的有符号整数类型 T (标准扩展)其中 min<T>max<T>std::numeric_limits<T>::min() 的缩写分别是 std::numeric_limits<T>::max() .

此外,如果我们假设 ab 是相同或不同基本有符号整数类型(标准或扩展)的值,那么 a - bdecltype(a - b) 中定义良好且可表示,只要 ab 都是负数或两者都是非负面的 .

1 回答

  • 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以及有符号和无符号整数类型统称为整数类型 . 整数类型的同义词是整数类型 . 整数类型的表示应使用纯二进制计算系统定义值 .

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

相关问题