代码之家  ›  专栏  ›  技术社区  ›  Chas. Owens

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

  •  18
  • Chas. Owens  · 技术社区  · 15 年前

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

    2 回复  |  直到 12 年前
        1
  •  40
  •   kennytm    15 年前

    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+B一% 应平等 .

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


    类似地,在C++ 98中,结果是按照C89的定义定义的(5.6/4)实现,但提到了圆对零规则是优选的,

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

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

    事实上,它成为C++ 0x(第5.6或4)中的标准规则:

    …对于积分操作数, / 算符产生代数商,去掉任何小数部分; 八十二

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

        2
  •  3
  •   Jens    12 年前

    在KennyTM的回答中添加一点细节:如果C标准要求 定义的实现 那么这个实现就是 必修的 记录它所做的选择。通常这会出现在编译器或库文档中(手册页、帮助手册、打印文档、CD小册子:-) 任何声称符合C89或更高版本的实现 必须 在某处提供。 尝试寻找这样的文档。在情况下 gcc 例如,这在GCC信息中:

    4 C实施定义的行为


    需要符合ISO C的实施来记录其 在每个指定区域的行为选择 “实施已定义”。以下列出了所有这些领域, 具有ISO/IEC 9899:1990和ISO/IEC中的章节号 9899:1999标准。有些领域只是在一个 标准的版本。

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

    • 菜单:

    • 翻译实施:

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