C++ 中带负数的整数除法舍入

发布于 2024-07-09 07:02:32 字数 406 浏览 14 评论 0原文

假设ab都是int类型,并且b非零。 考虑在以下情况下执行 a/b 的结果:

  1. ab 均为非负。
  2. ab 都是负数。
  3. 其中之一是负面的。

在情况 1 中,结果向下舍入到最接近的整数。 但是标准对案例 2 和案例 3 有何规定呢? 我在互联网上发现的一份旧草案表明它取决于实现(是的,甚至是情况 2),但委员会倾向于使其始终“向零舍入”。 有谁知道(最新)标准怎么说? 请仅根据标准回答,而不是根据什么有意义或特定编译器做什么。

Suppose a and b are both of type int, and b is nonzero. Consider the result of performing a/b in the following cases:

  1. a and b are both nonnegative.
  2. a and b are both negative.
  3. Exactly one of them is negative.

In Case 1 the result is rounded down to the nearest integer. But what does the standard say about Cases 2 and 3? An old draft I found floating on the Internet indicates that it is implementation dependent (yes, even case 2) but the committee is leaning toward making it always 'round toward zero.' Does anyone know what the (latest) standard says? Please answer only based on the standard, not what makes sense, or what particular compilers do.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

风吹短裙飘 2024-07-16 07:02:32

作为其他答案的更新:

C++11 的最后一个草案,n3242 在大多数实际用途中与实际的 C++11 标准相同,在 5.6 第 4 点(第 118 页)中这样说:

对于整数操作数 / 运算符产生代数商
丢弃任何小数部分; (见注释80)

注释 80 指出(注意注释是非规范性的):

80) 这通常称为向零截断。

第 4 点继续指出:

如果商 a/b 可以用结果类型表示,
(a/b)*b + a%b 等于 a。

可以证明,要求 a%b 的符号与 a 的符号相同(当不为零时)。

As an update to the other answers:

The last draft of C++11, n3242 which is for most practical purposes identical to the actual C++11 standard, says this in 5.6 point 4 (page 118):

For integral operands the / operator yields the algebraic quotient
with any fractional part discarded; (see note 80)

Note 80 states (note that notes are non-normative):

80) This is often called truncation towards zero.

Point 4 goes on to state:

if the quotient a/b is representable in the type of the result,
(a/b)*b + a%b is equal to a.

which can be shown to require the sign of a%b to be the same as the sign of a (when not zero).

瘫痪情歌 2024-07-16 07:02:32

根据 2008 年 5 月修订版,

您是对的:

二元 / 运算符产生商,二元 % 运算符产生第一个表达式除以第二个表达式的余数。 如果 / 或 % 的第二个操作数为零,则行为未定义; 否则 (a/b)*b + a%b 等于 a。 如果两个操作数都非负,则余数也非负; 如果不是,则余数的符号是​​实现定义的75)。

注释 75 说:

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

C++ 在这方面很可能会落后于 C。 就目前情况而言,它是未定义的,但他们着眼于改变它。

我和 Stroustrup 在同一个部门工作,并与委员会的一名成员一起工作。 事情需要很长时间才能完成,而且它的政治性永无休止。 如果这看起来很愚蠢,那么它很可能就是这样。

According to the May 2008 revision,

You're right:

The binary / operator yields the quotient, and the binary % operator yields the remainder from the division of the first expression by the second. If the second operand of / or % is zero the behavior is undefined; otherwise (a/b)*b + a%b is equal to a. If both operands are nonnegative then the remainder is nonnegative; if not, the sign of the remainder is implementation-defined75).

Note 75 says:

According to work underway toward the revision of ISO C, the preferred algorithm for integer division follows the rules defined in the ISO Fortran standard, ISO/IEC 1539:1991, in which the quotient is always rounded toward zero.

Chances are that C++ will lag C in this respect. As it stands, it's undefined but they have an eye towards changing it.

I work in the same department as Stroustrup and with a member of the committee. Things take AGES to get accomplished, and its endlessly political. If it seems silly, it probably is.

べ繥欢鉨o。 2024-07-16 07:02:32

只是一个评论。 C++ 标准的当前工作草案确实纠正了“实现定义”问题并要求截断为零。 这里是委员会的网页,这里是草案。 该问题在第 112 页。

Just a comment. The current working draft for the C++ standard indeed corrects the "implementation-defined" issue and asks for truncation towards zero. Here is the committee's webpage, and here is the draft. The issue is at page 112.

听风吹 2024-07-16 07:02:32

有时我们需要退一步,看看它的数学原理:

给定 int x, int y

如果 int i1 = x/y 并且
int i2 = x%y

那么 y * i1 + i2 必须是 x

所以这与标准无关,但只有一种可能的方式。 如果任何标准允许以任何其他方式进行,那么该标准就是错误的,这意味着语言被破坏了。

Sometimes we need to take a step back, and look just at the mathematics of it:

Given int x, int y

if int i1 = x/y and
int i2 = x%y

then y * i1 + i2 must be x

So this is not so much about the standard, but there is only one way this can possibly be. If any standards allows it to be any other way, then the standard is wrong, and that means the language is broken.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文