例如,假设您有以下变量:
int i = 9;
int j = 7;
根据实现的不同,(-i)/j
的值可能是-1
或-2
。如何可能获得这两个不同的结果?
int i = 9;
int j = 7;
根据实现的不同,(-i)/j
的值可能是-1
或-2
。如何可能获得这两个不同的结果?
令人惊讶的是,C89中对此的结果是实现定义的:
ANSI草案 § 3.3.5
当整数相除且除法不精确时,如果两个操作数都是正数,则 / 运算符的结果是代数商小于最大整数,% 运算符的结果为正数。 如果任何一个操作数为负数,则无论代数商小于最大整数还是大于最小整数, / 运算符的结果都是实现定义的。
但是在C99中已经发生了改变:
N1256 § 6.5.5/6
当整数相除时,/ 运算符的结果是代数商去掉任何小数部分*
有一注脚:
* 这通常被称为“向零截断”
澄清一下,“实现定义”意味着实现必须决定哪个结果,这并不意味着有时会得到一种结果,有时会得到另一种结果(除非实现定义为执行像那样的奇怪操作)。
/
的结果在负操作数情况下可能会被截断为向上或向下(在C99中,结果将被截断为朝零方向)。历史原因在C99理论基础中有所解释:在C89中,涉及负操作数的整数除法可以以一种实现定义的方式向上或向下四舍五入;目的是为了避免在运行时代码中产生开销去检查特殊情况并强制实施特定行为。然而,在Fortran中,结果总是朝零方向截断,这样的开销似乎对数字编程社区来说是可接受的。因此,C99现在要求类似的行为,这应该有助于从Fortran到C的代码移植。