为什么使用模数时C ++输出负数? [英] Why does C++ output negative numbers when using modulo?

查看:206
本文介绍了为什么使用模数时C ++输出负数?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

数学



如果您有如下方程式:

  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>维基百科,了解不同语言中模数的长列表。

idiv ( 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 positive m:

    #!/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, in AX and DX respectively). This is used in the C library function divmod, 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆