【问题标题】:Are there any implementations that support a negative zero, or reserve it as a trap representation?是否有任何实现支持负零,或将其保留为陷阱表示?
【发布时间】:2015-08-15 15:55:15
【问题描述】:

在当今的大多数实现中,符号位的位模式为 1,值位的位模式为全 0 的有符号整数值往往代表该有符号整数类型的最低可能值。

但是,正如6.2.6.2p2 所说,这不是必需的:

这些应用中的哪一个是实现定义的,无论符号位为 1 且所有值位为零(对于前两个),还是符号位和所有值位为 1(对于一个补码)的值是陷阱表示或正常值。

我的第一个问题很简单:是否有任何实现将此位模式用于负零或陷阱表示?如果这个问题的答案是“否”,那么我的后续问题的答案也必须是“否”。

继该问题之后,6.2.6.2p3 指出,当将负零分配给对象时,它可能(或可能不会)转换为常规零:

未指定这些情况实际上是生成负零还是正常零,以及当存储在对象中时负零是否变为正常零。

我的后续问题:

  1. 是否有任何实现使用陷阱表示而不是该位模式的负零?
  2. 是否有任何实现使用存储为不同值的负零?
  3. 是否有任何使用存储为常规零的负零的实现?

编辑澄清:我询问在使用补码、二进制补码或有符号整数的符号和幅度表示的系统中理论上可能发生什么。我可以在本问题前面引用的部分中找到(并且已经找到)该信息。我问的是实际做了什么

【问题讨论】:

  • One's complement 具有不同的负零位模式。
  • 我相信 OS 2200 上的 UCS(在 Unisys Clearpath Dordado 大型机上,它们是一个补码机器)是使用一个补码的 C 实现,其中 +ve 和 -ve zero 是单独的位模式。跨度>
  • @undefinedbehaviour 不,我只是在 cmets 中回答您问题的第 2 点 :)
  • @undefinedbehaviour 没有可能。一个补码有两个零:一个正数和一个负数。全零位模式为正零,全一位模式为负零。
  • @orlp 我会为您简化...您可以在上面找到与有符号整数表示相关的 C 标准部分。在这个问题中,我已经两次链接到它。请不要回复,除非您有引用(来自 C 标准,因为这里没有其他相关内容)支持您的声明,或者准备停止做出不光彩和无效的断言。

标签: c c99 c11


【解决方案1】:

正如 cmets 中的 Iskar Jarak 引起我注意的那样,最近于 2015 年 2 月发布的 OS2200 具有称为 UCS C 的 C 实现,其中 @987654322 @文档

  • 符合标准的 C 实现,其中 -by "... 不使用 CONFORMANCE/TWOSARITH,在所有使用小于 () 的无符号比较中,(236)-1 大于零。"
  • 一个有问题的 C 实现,其中 “CONFORMANCE/TWOSARITH 导致负零 (236)-1,被生成的代码视为一个大的无符号整数。” 因为这违反了几个 C 标准条款(6.2.6.2p2 声明 “符号位的值是 -(2M)(二进制补码)”“符号位的值为 -(2M-1)(反码)”6.3.1.1p3 声明 “整数提升保留值包括符号”,与 UCS/OS2200 文档中指定的大无符号整数的转换相矛盾)因此只有当负零位模式被视为陷阱表示时才能符合,其中-by undefined 行为被调用,因此标准的约束不再适用。

总之,...

是否有任何实现将此位模式用于负零或陷阱表示?

是的。提供的示例可以将此位模式用于负零陷阱表示,具体取决于编译器一致性选项。


对于后续问题 1 和 2,OS2200 上的 UCS C 是这两个示例。

至于问题3,改天再回答……我的时间到这里结束了:)

【讨论】:

  • 该实现是否定义了至少 64 位的无符号类型?我看过的最接近一致的一个补码系统有一个无符号的 36 位类型和一个有符号的 72 位类型,但没有无符号的 72 位类型。
  • @supercat 我们指的是同一个实现吗?如果是这样,从文档中可以看出这是一个二进制补码系统,具有陷阱和/或不一致的负零位模式。根据上面链接的文档(声称“最新的编程语言标准”,呵呵),“长整数上不允许使用无符号属性”,尽管这个实现应该很容易实现unsigned long long...你说得对;这似乎是一个合规问题。
  • 必须是一个不同的系统(我在想一个 36 位的补码平台),但我怀疑所有符合 C99 的平台都适用于具有自然包装二进制补码语义的平台,因为 64-在这样的平台上,位或更大的无符号类型会很昂贵,除非它的字长为 65 位或更大。
  • 丢弃符号位(将其视为填充)会很昂贵吗?事实上,这个实现似乎是通过合并两个longs 来创建一个long long...“昂贵!” ;)
  • 我不知道这是否是我读到的那些补码的实现,也不是这个实现,或者上半部分是否按 (2^36-1) 缩放而不是 (2^36)。如果不要求无符号数具有二次幂模数,则可以有效地执行长无符号算术模 (2^36-1)^2,但获得二次幂模数会困难得多。请注意,即使文档只承诺有符号值的范围为 2^70-1,它实际上可能会扩展到 (2^36-1)(2^35)-1。
猜你喜欢
  • 1970-01-01
  • 2011-10-07
  • 2011-01-18
  • 1970-01-01
  • 2011-01-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-09-19
相关资源
最近更新 更多