为什么使用模数时C ++输出负数? [英] Why does C++ output negative numbers when using modulo?
问题描述
数学:
:如果您有如下方程式:
x = 3 mod 7
4,3,10,17,...,或更一般地:
x = 3 + k * 7 $ b b
其中k可以是任何整数。我不知道为数学定义模运算,但是因子环肯定是。
Python :
在Python中,当你使用%
时,你总是得到非负值。 code>:
#!/ usr / bin / python
# - * - encoding: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
strong> 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乘法运算符:
< blockquote>
二进制/运算符产生商,二进制%运算符
产生第一个表达式除以
秒的余数。如果/或%的第二个操作数为零,则行为是
undefined;否则(a / b)* b + a%b等于a。如果两个操作数都是
非负的,那么余数是非负的;如果没有,
剩余部分的符号由实现定义74)。
74)根据修订ISO C的工作,
整数除法的优选算法遵循在
ISO Fortran标准ISO / IEC 1539:1991,其中商是
,总是舍入为零。
资料来源:。由于您可以在使用此算法前使两个数字都为正, )
请参阅
a href =http://en.wikipedia.org/wiki/Modulo_operation#Remainder_calculation_for_the_modulo_operation>维基百科,了解不同语言中模数的长列表。 div
用于无符号值),它产生商和余数(对于字大小的参数,在 AX
和 DX
)。这在C库函数 divmod
中使用,它可以由编译器优化为单个指令! 整数除法遵守两个规则:
- 非整数商舍入到零;
- 结果满足方程
dividend = quotient * divisor + remainder
ul>
因此,当用负数除负数时,商将为负数(或零)。
因此,这种行为可以被视为一系列局部决策的结果:
- 处理器指令集设计针对常见情况
- 一致性(向零舍入,并遵守除法方程)优于数学正确性;
- 更倾向于效率和简单(特别是考虑到将C视为高级汇编的倾向);和
- C ++喜欢与C的兼容性。
Math:
If you have an equation like this:
x = 3 mod 7
x could be ... -4, 3, 10, 17, ..., or more generally:
x = 3 + k * 7
where k can be any integer. I don't know of a modulo operation is defined for math, but the factor ring certainly is.
Python:
In Python, you will always get non-negative values when you use
%
with a positivem
:#!/usr/bin/python # -*- coding: utf-8 -*- m = 7 for i in xrange(-8, 10 + 1): print(i % 7)
Results in:
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; }
Will output:
-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 Multiplicative operators:
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).
and
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.
Source: ISO/IEC 14882:2003(E)
(I couldn't find a free version of
ISO/IEC 1539:1991
. Does anybody know where to get it from?)The operation seems to be defined like this:
Question:
Does it make sense to define it like that?
What are arguments for this specification? Is there a place where the people who create such standards discuss about it? Where I can read something about the reasons why they decided to make it this way?
Most of the time when I use modulo, I want to access elements of a datastructure. In this case, I have to make sure that mod returns a non-negative value. So, for this case, it would be good of mod always returned a non-negative value. (Another usage is the Euclidean algorithm. As you could make both numbers positive before using this algorithm, the sign of modulo would matter.)
Additional material:
See Wikipedia for a long list of what modulo does in different languages.
解决方案On x86 (and other processor architectures), integer division and modulo are carried out by a single operation,
idiv
(div
for unsigned values), which produces both quotient and remainder (for word-sized arguments, inAX
andDX
respectively). This is used in the C library functiondivmod
, which can be optimised by the compiler to a single instruction!Integer division respects two rules:
- Non-integer quotients are rounded towards zero; and
- the equation
dividend = quotient*divisor + remainder
is satisfied by the results.
Accordingly, when dividing a negative number by a positive number, the quotient will be negative (or zero).
So this behaviour can be seen as the result of a chain of local decisions:
- Processor instruction set design optimises for the common case (division) over the less common case (modulo);
- Consistency (rounding towards zero, and respecting the division equation) is preferred over mathematical correctness;
- C prefers efficiency and simplicitly (especially given the tendency to view C as a "high level assembler"); and
- C++ prefers compatibility with C.
这篇关于为什么使用模数时C ++输出负数?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!