负数取余运算



原文:http://ceeji.net/blog/mod-in-real/


正整数的取余运算大家都很熟悉,但是对于负数、实数的取余运算,确实给人很新鲜的感觉。于是我对


此进行了一些探索。我发现,这里面还是颇有一点可以探索的东西的。


自然数的取模运算的定义是这样的(定义1):


如果a和d是两个自然数,d非零,可以证明存在两个唯一的整数 q 和 r,满足 a = qd + r 且0 ≤ r < d


。其中,q 被称为商,r 被称为余数。


那么对于负数,是否可以沿用这样的定义呢?我们发现,假如我们按照正数求余的规则求 (-7) mod 3 


的结果,就可以表示 -7 为 (-3)* 3 +2。其中,2是余数,-3是商。


那么,各种编程语言和计算器是否是按照这样理解的呢?下面是几种软件中对此的理解。


C++(G++ 编译): cout << (-7) % 3; // 输出 -1


Java(1.6): System.out.println((-7) % 3); // 输出 -1


Python 2.6:>>>  (-7) % 3 // 输出 2


百度计算器:(-7) mod 3 = 2


Google 计算器:(-7) mod 3 = 2


有道计算器:(-7) mod 3 = -1可以看到,结果特别有意思。这个问题是百家争鸣的。看来我们不能直


接把正数的法则加在负数上。实际上,在整数范围内,自然数的求余法则并不被很多人所接受,大家大


多认可的是下面的这个定义2。 
如果a 与d 是整数,d 非零,那么余数 r 满足这样的关系:


a = qd + r , q 为整数,且0 ≤ |r| < |d|。


可以看到,这个定义导致了有负数的求余并不是我们想象的那么简单,比如,-1 和 2 都是 (-7) mod 3 


正确的结果,因为这两个数都符合定义。这种情况下,对于取模运算,可能有两个数都可以符合要求。


我们把 -1 和 2 分别叫做正余数和负余数。通常,当除以d 时,如果正余数为r1,负余数为r2,那么有


r1 = r2 + d


对负数余数不明确的定义可能导致严重的计算问题,对于处理关键任务的系统,错误的选择会导致严重


的后果。


看完了 (-7) mod 3,下面我们来看一看 7 mod (-3) 的情况(看清楚,前面是 7 带负号,现在是 3 带


负号)。根据定义2,7 = (-3) * (-2) + 1 或7 = (-3) * (-3) -2,所以余数为 1 或 -2。


C++(G++ 编译): cout << 7 % (-3); // 输出 1


Java(1.6): System.out.println(7 % (-3)); // 输出 1


Python 2.6:>>>  输出 -2


百度计算器:7 mod (-3) = -2


Google 计算器: 7 mod (-3) = -2


有道计算器:不支持
从中我们看到几个很有意思的现象: 
Java 紧随 C++ 的步伐,而 Python、Google、百度步调一致。难道真是物以类聚?联想一下,


Google 一直支持 Python,Python 也颇有 Web 特色的感觉,而且 Google Application Engine 也


用的 Python,国内的搜索引擎也不约而同地按照 Google 的定义进行运算。 
可以推断,C++ 和 Java 通常会尽量让商更大一些。比如在 (-7) mod 3中,他们以 -2 为商,余数为 


-1。在 Python 和 Google 计算器中,尽量让商更小,所以以 -3 为商。在 7 mod (-3) 中效果相同:


C++ 选择了 3 作为商,Python 选择了 2 作为商。但是在正整数运算中,所有语言和计算器都遵循了


尽量让商小的原则,因此 7 mod 3 结果为 1 不存在争议,不会有人说它的余数是-2。 
如果按照第二点的推断,我们测试一下 (-7) mod (-3),结果应该是前一组语言(C++,Java)返回 2


,后一组返回 -1。(请注意这只是假设) 
于是我做了实际测试:


C++(G++ 编译): cout << (-7) % (-3); // 输出 -1


Java(1.6): System.out.println((-7) % (-3)); // 输出 -1


Python 2.6:>>>  输出 -1


百度计算器:-7 mod (-3) = -1


Google 计算器: -7 mod (-3) = -1


结果让人大跌眼镜,所有语言和计算机返回结果完全一致。


总结时间到
我们由此可以总结出下面两个结论: 
对于任何同号的两个整数,其取余结果没有争议,所有语言的运算原则都是使商尽可能小。 
对于异号的两个整数,C++/Java语言的原则是使商尽可能大,很多新型语言和网页计算器的原则是使


商尽可能小。 
最后是拓展时间。对于实数,我们也可以定义取模运算(定义3)。 
当a 和 d 是实数,且d 非零, a 除以 d 会得到另一个实数(商),没有所谓的剩余的数。但如果要求商


为一个整数,则余数的概念还是有必要的。可以证明:存在唯一的整数商 q 和唯一的实数 r 使得: a = 


qd + r, 0 ≤ r < |d|.(转自维基百科)
如上在实数范围内扩展余数的定义在数学理论中并不重要,尽管如此,很多程序语言都实现了这个定义


。至于哪些程序语言实现了这个定义,就留给大家自己探究吧! 















<think>好的,我现在需要回答用户关于Python运算的使用方法和示例的问题。首先,我得回忆一下Python运算的基本知识,确保自己理解正确。根据用户提供的引用内容,特别是引用[1]、[3]和[4],运算Python中使用%符号,并且遵循算术模运算的定义。同时,divmod()函数也可以实现运算,返回商和数。 接下来,我需要组织回答的结构,确保符合用户的要求:结构清晰,逐步解决问题,保证真实可靠。可能需要分几个部分,比如基本用法、处理负数的情况、浮点数的,以及使用divmod()函数的示例。 首先,基本用法部分,应该用简单的例子,比如整数相除的数,如20%3=2,这样用户容易理解。然后,要提到负数的情况,因为这里可能会有陷阱。根据引用[1],Python结果符号与除数的符号一致,所以例如-5%3应该是1,而5%-3应该是-1,这可能需要详细说明,避免混淆。 接下来是浮点数的运算,例如10.5%3,结果是1.5,这里要确保例子正确,同时提醒用户注意浮点数的精度问题。 然后,介绍divmod()函数,展示如何同时获商和数,比如divmod(20,3)返回(6,2),这需要和%操作符对比说明其便利之处。 在编写过程中,要注意使用用户指定的格式,行内公式用$...$,独立公式用$$...$$,并且检查LaTeX语法是否正确。例如,在解释数学公式时,如a = b * q + r,其中r的符号与b一致,需要用行内公式包裹。同时,需要生成相关问题,参考用户示例中的结构,提出三个相关问题,如运算的数学原理、处理负数时的注意事项、divmod()的应用场景等。 还要确保引用正确,每个引用来源在回答的适当位置添加标识,如引用[^1]、[^3]等,特别是在提到Python定义和divmod()函数时,对应到用户提供的引用内容。 最后,检查整个回答是否符合格式要求,没有使用markdown,正确使用中文,代码块用反引号包裹,并确保示例代码正确无误。比如,用户提供的代码示例中,运算的示例是否正确,是否需要调整。 可能还需要验证一些例子,比如负数的结果是否符合Python的实际输出,避免给出错误的信息。例如,-5%3在Python中确实返回1,而5%-3返回-1,这样的例子能帮助用户理解数符号的规则。 总结下来,回答的结构大致如下: 1. 基本使用方法:%操作符的语法和整数示例。 2. 处理负数的情况:数符号与除数一致,举例说明。 3. 浮点数:给出浮点数的例子。 4. divmod()函数的使用:示例展示商和数的获。 5. 注意事项:提及特殊情况,如除数为0的错误。 然后生成相关问题,确保问题相关且有价值,帮助用户进一步学习。 在写作过程中,需要保持语言简洁明了,避免专业术语过多,让初学者也能理解。同时,确保所有信息准确,引用正确来源,如引用提到%和divmod()两种方法,需要在相应部分引用。 现在开始将这些思考整理成结构化的回答,并插入合适的示例代码和公式,最后生成相关问题。</think>### Python运算使用方法及示例 Python中的运算用于计算两个数相除后的数,主要通过`%`运算符实现,也可用`divmod()`函数同时获商和数。以下是具体说明: --- #### **1. 基本使用方法** 使用`%`运算符进行运算: ```python a = 20 b = 3 print(a % b) # 输出2 ``` 这里$20 = 3 \times 6 + 2$,数为2[^3]。 --- #### **2. 处理负数的情况** Python结果符号与**除数**一致: ```python print(-5 % 3) # 输出1(除数3为正,数为正) print(5 % -3) # 输出-1(除数-3为负,数为负) ``` 数学公式为:$a = b \times q + r$,其中$r$的符号与$b$相同。 --- #### **3. 浮点数运算** `%`运算符支持浮点数: ```python print(10.5 % 3) # 输出1.5(10.5 = 3×3 + 1.5) print(7.8 % 2.5) # 输出0.3(7.8 = 2.5×3 + 0.3) ``` --- #### **4. 使用divmod()函数** `divmod(a, b)`返回商和数的元组: ```python quotient, remainder = divmod(20, 3) print(quotient) # 输出6 print(remainder) # 输出2 ``` 等价于同时执行`a // b`(整除)和`a % b`。 --- #### **5. 注意事项** - **除数为0会报错**:`5 % 0`会引发`ZeroDivisionError`。 - **运算优先级**:运算符优先级与乘除相同,必要时需加括号。 ---
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值