【问题标题】:Does either ANSI C or ISO C specify what -5 % 10 should be?ANSI C 或 ISO C 是否指定 -5 % 10 应该是什么?
【发布时间】:2011-04-06 07:00:25
【问题描述】:

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

【问题讨论】:

标签: c c99 modulo c89


【解决方案1】:

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) 这通常称为向零截断。

【讨论】:

    【解决方案2】:

    为 KennyTM 的回答添加一点细节:如果 C 标准调用了定义的实现,那么需要该实现来记录它所做的选择。通常这将在编译器或库文档中(手册页、帮助手册、印刷文档、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)实现定义的行为。 一些选择是由库和操作系统(或其他 为独立环境编译时的环境);参考 他们的文档以获取详细信息。

    • 菜单:

    • 翻译实现::

    • 环境实现::
    • 标识符实现::
    • 字符实现::
    • 整数实现::
    • 浮点实现::
    • 数组和指针实现::
    • 提示实现::
    • 结构联合枚举和位域实现::
    • 限定符实现::
    • 声明器实现::
    • 语句实现::
    • 预处理指令实现::
    • 库函数实现::
    • 架构实现::
    • 特定于语言环境的行为实现::

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-05-13
      • 2015-05-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-07-08
      相关资源
      最近更新 更多