19

我似乎记得ANSI C没有指定当模运算符的任一操作数为负时应返回什么值(只是它应该是一致的)。是后来指定的,还是总是指定的,我记错了?

4

2 回答 2

40

C89,不完全(§3.3.5/6)。它可以是 -5 或 5,因为 -5 / 10 可以返回 0 或 -1(根据涉及和的%线性方程定义):/*+

当整数被除且除法不精确时,如果两个操作数都是正数,则/运算符的结果是小于代数商的最大整数,并且%运算符的结果是正数。 如果任一操作数为负数,则/运算符的结果是小于代数商的最大整数还是大于代数商的最小整数是实现定义的,运算符结果的符号也是如此%。如果商a/b是可表示的,则表达式(a/b)*b + a%b应等于a

C99,是的(第 6.5.5/6 节),结果必须是 -5:

当整数被除法时,/运算符的结果是代数商,其中任何小数部分被丢弃。88)如果商a/b是可表示的,则表达式(a/b)*b + a%b应等于a

88) 这通常被称为“向零截断”。


类似地,在 C++98 中,结果是实现定义的(第 5.6/4 节),遵循 C89 的定义,但提到首选向零舍入的规则,

...如果两个操作数都是非负数,则余数是非负数;如果不是,则余数的符号是​​实现定义的74)

74)根据正在进行的 ISO C 修订工作,整数除法的首选算法遵循 ISO Fortran 标准 ISO/IEC 1539:1991 中定义的规则,其中商总是向零舍入。

实际上它成为了 C++0x (§5.6/4) 中的标准规则:

...对于整数操作数,/运算符产生代数商,丢弃任何小数部分;82 ...

82) 这通常被称为向零截断。

于 2010-08-31T13:47:28.413 回答
3

为 KennyTM 的回答添加一点细节:如果 C 标准调用定义的实现,则需要该实现来记录它所做的选择。通常这将在编译器或库文档中(手册页、帮助手册、印刷文档、CD 小册子 :-) 任何声称符合 C89 或更高版本的实现都必须在某处提供。尝试寻找这样的文件。例如gcc,这是在 gcc-info 中:

4 C 实现定义的行为


ISO C 的符合要求的实施需要记录其在每个被指定为“实施定义”的领域中的行为选择。下面列出了所有这些领域,以及 ISO/IEC 9899:1990 和 ISO/IEC 9899:1999 标准中的章节编号。某些领域仅在标准的一个版本中实现定义。

一些选择取决于 GCC 遵循的平台(包括标准字符编码)的外部确定 ABI;这些在下面被列为“由 ABI 确定”。*注意二进制兼容性:兼容性,和`http://gcc.gnu.org/readings.html'。预处理器手册中记录了一些选择。*注意实现定义的行为:(cpp)实现定义的行为。一些选择是由库和操作系统(或为独立环境编译时的其他环境)做出的;有关详细信息,请参阅他们的文档。

  • 菜单:

  • 翻译实施::

  • 环境实施::
  • 标识符实现::
  • 字符实现::
  • 整数实现::
  • 浮点实现::
  • 数组和指针实现::
  • 提示实现::
  • 结构联合枚举和位域实现::
  • 限定符实施::
  • 声明器实现::
  • 报表实现::
  • 预处理指令实现::
  • 库函数实现::
  • 架构实现::
  • 特定于语言环境的行为实现::
于 2012-12-23T17:16:20.747 回答