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

数学:


如果您有这样的方程式:


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乘法运算符:


二进制/操作员产生的商,和二进制%操作者产生了由第二所述第一表达的除法的余数。如果/或%的第二个操作数为零,则行为不确定。否则(a / b)* b + a%b等于a。如果两个操作数均为非负数,则其余为非负数;如果不是,则其余的符号由实现定义74)。



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


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


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


该操作似乎是这样定义的:


在此处输入图片说明


问题:


这样定义它是否有意义?


此规范的参数是什么?制定这样的标准的人是否有讨论的地方?在哪里可以阅读有关他们决定采用这种方式的原因的一些信息?


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


附加材料:


有关不同语言的模运算的详细列表,请参见Wikipedia。


qq_笑_17
浏览 699回答 3
3回答

米琪卡哇伊

在x86(和其他处理器体系结构)上,整数除法和模是通过单个操作idiv(div对于无符号值)执行的,该操作会产生商和余数(分别针对in&nbsp;AX和in的字长参数DX)。C库函数中使用了该函数divmod,编译器可以将其优化为单个指令!整数除法遵守两个规则:非整数商将舍入为零;和dividend = quotient*divisor + remainder结果满足了方程式。因此,当将负数除以正数时,商将为负(或零)。因此,这种行为可以看作是一系列本地决策的结果:处理器指令集设计针对较普通情况(模)优化了普通情况(除法);一致性(四舍五入并遵守除法方程)比数学正确性更可取;C更喜欢效率并且要简单(特别是倾向于将C视为“高级汇编程序”);和C ++更喜欢与C兼容。

Smart猫小萌

此规范的参数是什么?C ++的设计目标之一是有效地映射到硬件。如果底层硬件以产生负余数的方式实现除法,那么这就是%在C ++中使用时得到的结果。真的就是全部。制定这样的标准的人是否有讨论的地方?您将在comp.lang.c ++。moderated上找到有趣的讨论,并在较小程度上找到comp.lang.c ++
打开App,查看更多内容
随时随地看视频慕课网APP