ANSI C或ISO C是否规定了-5%10应该是什么?

20

我记得 ANSI C 没有规定当模运算符的任一操作数为负数时应返回什么值(只是要保持一致)。后来是否有规定,还是一直都有规定而我记错了?


1
可能是负数取模操作的重复问题。 - Ciro Santilli OurBigBook.com
2个回答

40
C89的规范(§3.3.5/6)仅在两个操作数均为正数时,将`/`运算符的结果定义为代数商小于此值的最大整数,并将`%`运算符的结果定义为正数。如果其中一个操作数为负,则`/`运算符的结果是代数商小于或大于此值的最大或最小整数,其余数的符号为实现定义。如果商`a/b`可表示,则表达式`(a/b)*b+a%b`应等于`a`。对于算术除法,有两种可能的商和余数,因此结果可以是-5或5。
相反,C99的规范(§6.5.5/6)在所有情况下都使用代数商,并将商作为整数返回。如果商`a/b`可表示,则表达式`(a/b)*b+a%b`应等于`a`。这通常被称为“朝零方向舍入”。
类似地,在C++98中(§5.6/4),如果两个操作数均为非负数,则余数为非负数;否则,余数的符号为实现定义。虽然遵循了C89的定义,但提到了向零舍入规则更受欢迎。

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

实际上,在 C++0x(§5.6/4)中,这成为标准规则:

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

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


3
补充一下KennyTM的回答:如果C标准称某些内容为“实现定义”,那么该实现必须记录其所做的选择。通常这会在编译器或库的文档(man页面、帮助手册、打印文档、CD手册等)中提供。任何声称符合C89或更高版本的实现必须在某个地方提供此信息。建议查找此类文档。以gcc为例,可以在gcc-info中找到相关信息:
4 C实现定义行为
遵循ISO C的合规实现需要在每个被指定为实现定义的领域中记录其行为选择。以下列出了所有这样的领域,以及来自ISO/IEC 9899:1990和ISO/IEC 9899:1999标准的章节编号。一些区域仅在标准的一个版本中被定义为实现定义。
某些选择取决于平台的外部确定ABI(包括标准字符编码),GCC遵循这些选择;在下面列为“由ABI确定”。请参阅二进制兼容性:兼容性和http://gcc.gnu.org/readings.html。某些选择在预处理器手册中有记录。请参阅实现定义行为:(cpp)实现定义行为。某些选择由库和操作系统(或其他环境在编译自由环境时)进行;有关详细信息,请参阅它们的文档。
菜单: - 翻译实现:(链接) - 环境实现: - 标识符实现: - 字符实现: - 整数实现: - 浮点实现: - 数组和指针实现: - 提示实现: - 结构联合枚举和位字段实现: - 限定符实现: - 声明器实现: - 语句实现: - 预处理指令实现: - 库函数实现: - 架构实现: - 区域特定行为实现:

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接