为什么在 C89 中得到不同的整数除法值?
Why do you get different values for integer division in C89?
例如,假设您有这些变量:
int i = 9;
int j = 7;
根据具体实施,(-i)/j
的值可以是 –1
或 –2
。怎么可能得到这两个不同的结果?
令人惊讶的是,结果是 C89 中定义的实现:
ANSI draft § 3.3.5
When integers are divided and the division is inexact, if both
operands are positive the result of the / operator is the largest
integer less than the algebraic quotient and the result of the %
operator is positive. If either operand is negative, whether the
result of the / operator is the largest integer less than the
algebraic quotient or the smallest integer greater than the algebraic
quotient is implementation-defined
然而,这在 C99 中有所改变
N1256
§ 6.5.5/6
When integers are divided, the result of the / operator is the algebraic quotient with any fractional part discarded*
带脚注:
* This is often called "truncation toward zero"
澄清一下,"implementation defined" 意味着实现必须决定哪一个,这并不意味着有时你会得到一件事,有时你会得到另一件事(除非实现定义它真正做某事我猜这样很奇怪)。
在 C89 中,对于负操作数,除法 /
的结果可以任意截断。 (在 C99 中,结果将被截断为零。)
C99 Rationale中解释了历史原因:
Rationale for International Standard — Programming Languages — C §6.5.5 Multiplicative operators
In C89, division of integers involving negative operands could round upward or downward in an implementation-defined manner; the intent was to avoid incurring overhead in run-time code to check for special cases and enforce specific behavior. In Fortran, however, the result will always truncate toward zero, and the overhead seems to be acceptable to the numeric programming community. Therefore, C99 now requires similar behavior, which should facilitate porting of code from Fortran to C.
例如,假设您有这些变量:
int i = 9;
int j = 7;
根据具体实施,(-i)/j
的值可以是 –1
或 –2
。怎么可能得到这两个不同的结果?
令人惊讶的是,结果是 C89 中定义的实现:
ANSI draft § 3.3.5
When integers are divided and the division is inexact, if both operands are positive the result of the / operator is the largest integer less than the algebraic quotient and the result of the % operator is positive. If either operand is negative, whether the result of the / operator is the largest integer less than the algebraic quotient or the smallest integer greater than the algebraic quotient is implementation-defined
然而,这在 C99 中有所改变
N1256 § 6.5.5/6
When integers are divided, the result of the / operator is the algebraic quotient with any fractional part discarded*
带脚注:
* This is often called "truncation toward zero"
澄清一下,"implementation defined" 意味着实现必须决定哪一个,这并不意味着有时你会得到一件事,有时你会得到另一件事(除非实现定义它真正做某事我猜这样很奇怪)。
在 C89 中,对于负操作数,除法 /
的结果可以任意截断。 (在 C99 中,结果将被截断为零。)
C99 Rationale中解释了历史原因:
Rationale for International Standard — Programming Languages — C §6.5.5 Multiplicative operators
In C89, division of integers involving negative operands could round upward or downward in an implementation-defined manner; the intent was to avoid incurring overhead in run-time code to check for special cases and enforce specific behavior. In Fortran, however, the result will always truncate toward zero, and the overhead seems to be acceptable to the numeric programming community. Therefore, C99 now requires similar behavior, which should facilitate porting of code from Fortran to C.