c++ - 为什么 C++ 使用模数时输出负数?

标签 c++ standards modulo

数学:

如果你有这样的等式:

x = 3 mod 7

x 可以是 ... -4、3、10、17、...,或更一般地说:

x = 3 + k * 7

其中 k 可以是任何整数。我不知道为数学定义了模运算,但因子环肯定是。

Python:

在 Python 中,当您将 % 与正 m 一起使用时,您将始终得到非负值:

#!/usr/bin/python
# -*- coding: utf-8 -*-

m = 7

for i in xrange(-8, 10 + 1):
    print(i % 7)

结果:

6    0    1    2    3    4    5    6    0    1    2    3    4    5    6    0    1    2    3

C++:

#include <iostream>

using namespace std;

int main(){
    int m = 7;

    for(int i=-8; i <= 10; i++) {
        cout << (i % m) << endl;
    }

    return 0;
}

将输出:

-1    0    -6    -5    -4    -3    -2    -1    0    1    2    3    4    5    6    0    1    2    3    

ISO/IEC 14882:2003(E) - 5.6 乘法运算符:

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-defined 74).

74) 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.

来源:ISO/IEC 14882:2003(E)

(我找不到 ISO/IEC 1539:1991 的免费版本。有人知道从哪里获得它吗?)

操作好像是这样定义的:

enter image description here

问题:

这样定义有意义吗?

这个规范的论据是什么?创建此类标准的人是否有讨论它的地方?我在哪里可以了解他们决定这样做的原因?

大多数时候,当我使用模数时,我想访问数据结构的元素。在这种情况下,我必须确保 mod 返回一个非负值。因此,对于这种情况,最好 mod 总是返回一个非负值。 (另一种用法是 Euclidean algorithm。因为您可以在使用此算法之前将两个数字都设为正数,所以模的符号很重要。)

附加 Material :

Wikipedia了解模数在不同语言中的作用的长列表。

最佳答案

在 x86(和其他处理器架构)上,整数除法和取模由单个操作执行,idiv(div 用于无符号值),它产生两个商和余数(对于字大小的参数,分别在 AXDX 中)。这个用在C库函数divmod中,可以被编译器优化成单条指令!

整数除法遵循两个规则:

  • 非整数商向零舍入;和
  • 结果满足方程 dividend = quotient*divisor + 余数

因此,当一个负数除以一个正数时,商将为负数(或零)。

所以这种行为可以看作是一系列本地决策的结果:

  • 处理器指令集设计针对不太常见的情况(模)优化了常见情况(除法);
  • 一致性(向零舍入,并遵守除法方程)优于数学正确性;
  • C 更喜欢效率和简单(特别是考虑到将 C 视为“高级汇编程序”的趋势);和
  • C++ 更喜欢与 C 兼容。

关于c++ - 为什么 C++ 使用模数时输出负数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11630321/

相关文章:

c++ - 是否有用于 directx 9 c++ 的 irc 聊天室?

c++ - C++ 中的模幂运算

numbers - 当分母与m不互质时如何计算 "modular multiplicative inverse"?

python - 变量 +=% 可能或如何获取另一个数字之后的下一个数字间隔

c++ - 使用 SIGINT 停止进程时的 Valgrind 输出

c++ - 我如何在 for 循环内部或外部打印双变量

c++ - 对同一数据使用两个不同的结构

c++ - 为什么 ISO C++ 标准禁止对成员进行初始化?

c++ - new[] 是否在 C++ 中调用默认构造函数?

c++ - 转换 int -> unsigned long long 是否由标准定义