模运算符更改

发布于 2024-09-16 13:51:17 字数 610 浏览 5 评论 0原文

C++03 中的 $5.6/4 状态 - “如果两者 操作数是非负的,那么 余数为非负数;如果不是,则 余数的符号是 实现定义74)

其中注释 74 是

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

C++0x 状态 -

$5.6/4-“对于整数操作数,/ 运算符生成代数商,并丢弃任何小数部分;79 如果商 a/b 可在结果类型中表示,(a/b)*b + a%b 等于 a。

注释 79 所示

这通常称为向零截断。

所以我有两个问题:

  • 有人可以解释“向零截断”的概念吗?

  • 带有负操作数的模是 C++0x 中定义的行为吗?

$5.6/4 in C++03 states- "If both
operands are nonnegative then the
remainder is nonnegative;if not, the
sign of the remainder is
implementation-defined74).

where Note 74 is

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

C++0x states -

$5.6/4- "For integral operands the / operator yields the algebraic quotient with any fractional part discarded;79 if the quotient a/b is representable in the type of the result, (a/b)*b + a%b is equal to a.

Note 79 says

This is often called truncation towards zero.

So I have two questions:

  • Can someone explain this concept of 'truncation towards zero'?

  • Is modulus with negative operands a defined behavior in C++0x?

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

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

发布评论

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

评论(3

赠我空喜 2024-09-23 13:51:17

向零截断意味着通过选择下一个最接近零的整数将实数转换为整数。同样,您写下数字,并忽略小数点后的所有内容,无论数字是正数还是负数。

考虑 11/4 = 2.75 - 如果将其截断为零,则得到 2。

考虑 -11/4 或 11/-4 = -2.75 - 如果将其截断为零,则得到 -2。

对于某些数学运算来说,(a/b)*b + a%b == a 很重要。如果我们必须使这个方程成立,并且我们也接受整数除法向零截断,那么我们可以推导出 % 运算符的操作如下:

a == 11, b == 4:
a/b == 2, 2*4 + a%b == 11, therefore a%b == 3.

a == -11, b == 4:
a/b == -2, -2 * 4 + a%b == -11, therefore a%b == -3.

a == 11, b == -4:
a/b == -2, -2 * -4 + a%b == 11, therefore a%b == 3.

a == -11, b == -4:
a/b == 2, 2 * -4 + a%b == -11, therefore a%b == -3.

一开始可能会令人困惑,但 C++ 0x 使用方程 (a/b)*b + a%b == a 定义 a%b 运算符的行为。该方程甚至对于负数也成立,因此 a%b 是针对负数定义的。

Truncation towards zero means converting a real number to an integer by selecting the next integer nearest zero. Equivalently, you write the number down, and ignore everything after the decimal point, whether the number is positive or negative.

Consider 11/4 = 2.75 -- if you truncate this towards zero, you get 2.

consider -11/4 or 11/-4 = -2.75 -- if you truncate this towards zero, you get -2.

It's important for some maths operations that (a/b)*b + a%b == a. If we must make this equation hold, and we also accept that integer division truncates towards zero, then we can deduce the operation of the % operator as follows:

a == 11, b == 4:
a/b == 2, 2*4 + a%b == 11, therefore a%b == 3.

a == -11, b == 4:
a/b == -2, -2 * 4 + a%b == -11, therefore a%b == -3.

a == 11, b == -4:
a/b == -2, -2 * -4 + a%b == 11, therefore a%b == 3.

a == -11, b == -4:
a/b == 2, 2 * -4 + a%b == -11, therefore a%b == -3.

It might be confusing at first, but C++0x is defining the behaviour of the a%b operator using the equation (a/b)*b + a%b == a. This equation holds even for negative numbers, so a%b is defined for negative numbers.

浅听莫相离 2024-09-23 13:51:17

a) 考虑(±5)/(±3) -> ±1。在数轴上:

  (-5)/3                                     5/3
     5/(-3)                               (-5)/(-3)
      =                                       =
    -1.66 --> -1                       1 <-- 1.66
       v       v                       v       v
-  +  -  -  -  +  -  -  -  +  -  -  -  +  -  -  -  +  -
   |           |           |           |           |
  -2          -1           0           1           2

因此四舍五入朝向零。

b) 是的。由于现在为所有 abb == 0 除外)定义了 a/b,并且 < code>(a/b)*b + a%b == a,a%b 只有 1 个唯一解,因此 % 运算符对于所有 abb == 0 除外)也是很好的保护。

a) Consider (±5)/(±3) -> ±1. On the number line:

  (-5)/3                                     5/3
     5/(-3)                               (-5)/(-3)
      =                                       =
    -1.66 --> -1                       1 <-- 1.66
       v       v                       v       v
-  +  -  -  -  +  -  -  -  +  -  -  -  +  -  -  -  +  -
   |           |           |           |           |
  -2          -1           0           1           2

the rounding is thus towards zero.

b) Yes. Since a/b is now defined for all a and b (except b == 0), and (a/b)*b + a%b == a, there is only 1 unique solution for a%b, so the % operator is also well-defiend for all a and b (except b == 0).

请止步禁区 2024-09-23 13:51:17

a) “朝零截断”仅仅意味着任何小数部分都被截掉。截断后的数字始终至少与原始数字一样接近 0,并且通常更接近原始数字。

这在负数中最为明显,但目标是让使用 /% 与负数变得不那么棘手(因为目前,任何实现都可以处理它,但是它们选择)。 -7/4 可以有两种方式:-2 余数为 1,或 -1 余数为 -3。并且有编译器和处理器可以以两种方式处理它。由于 -7/4 实际上是 -1.75,“向零截断”会给你 -1,所以后一种方法是标准的。

b)
看起来就是这样。它始终是半定义的(“实现定义的”),但这看起来像是试图从一开始就定义什么应该是标准的。

a) "Truncation towards zero" simply means that any decimal part is lopped off. The truncated number is always at least as close to 0 as, and usually closer than, the original number.

This is most noticeable in negative numbers, but the goal is to make it less tricky to use / and % with negative numbers (since currently, any implementation can handle it however they choose). -7/4 can be thought of two ways: -2 with a remainder of 1, or -1 with a remainder of -3. And there are compilers and processors that handle it both ways. Since -7/4 is actually -1.75, "truncation toward zero" would give you -1, so the latter way is what'll be standard.

b)
That's what it looks like. It's always been semi-defined ("implementation-defined"), but this looks like an attempt to define what should have been standard from the beginning.

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