除数或被除数为负数时求余数问题

问题描述

首先可以看到不同编程语言下,求余数结果是不同的。我试了一些,具体如下。

算式/结果C++JavaJavaScriptPython
5 % -2111-1
-5 % 2-1-1-11
-5 % -2-1-1-1-1
5 % -3222-1
-5 % 3-2-2-21
-5 % -3-2-2-2-2
5 % -4111-3
-5 % 4-1-1-13
-5 % -4-1-1-1-1

为什么会有这样的结果?

解释

因为 不同编程语言对 % 运算符的定义不同

  • C/C++,Java,JavaScript 为 取余
  • Python 为 取模

取模运算(“Modulo Operation”)和取余运算(“Complementation ”)是有重叠部分但又不完全一致的两个概念。当除数和被除数均大于0时,求模运算和求余运算一致。而对于对 负整数 进行除法运算时操作却不同。取模主要是用于计算机术语中,取余则更多是数学概念。

假设有式子(a除以b等于c余数r):
a ÷ b = c ⋅ ⋅ ⋅ r a ÷ b = c ··· r a÷b=cr

  1. ab 均大于 0 时,求模运算和求余运算所得的 c 的值一致,r >= 0, 当 ab 有负数时,见下。

  2. 求余 运算时,当 r 不为 0, r 的符号和 a 一致。即 余数符号和被除数符号必须相同

  3. 求模 运算时,取除法的整数商默认优先取地板商,即往负无穷方向取最邻近整数。模运算具体实现过程为:

    举例说明
    5 mod -2 = 1商 = -2 或 -3,-3<-2,取商=-3,余 = -1
    -5 mod 2 = 1商 = -2 或 -3,-3<-2,取商=-3,余 = 1
    -5 mod -2 = 1商 = 2 或 3,2<3,取商=2,余 = -1

附加代码

估计同学们也用不到这些,就算是做个记录吧。

Java
[root@VM-0-9-centos YushuTest]# cat JavaTest.java
public class JavaTest
{
  public static void main(String[] args)
  {
    System.out.println("5 % -2 = " + (5%(-2)));
    System.out.println("-5 % 2 = " + ((-5)%2));
    System.out.println("-5 % -2 = " + ((-5)%(-2)));
    System.out.println("5 % -3 = " + (5%(-3)));
    System.out.println("-5 % 3 = " + ((-5)%3));
    System.out.println("-5 % -3 = " + ((-5)%(-3)));
    System.out.println("5 % -4 = " + (5%(-4)));
    System.out.println("-5 % 4 = " + ((-5)%4));
    System.out.println("-5 % -4 = " + ((-5)%(-4)));}
}
[root@VM-0-9-centos YushuTest]# javac JavaTest.java
[root@VM-0-9-centos YushuTest]# java JavaTest
5 % -2 = 1
-5 % 2 = -1
-5 % -2 = -1
5 % -3 = 2
-5 % 3 = -2
-5 % -3 = -2
5 % -4 = 1
-5 % 4 = -1
-5 % -4 = -1
C++
[root@VM-0-9-centos YushuTest]# cat CppTest.cpp
#include<iostream>
using namespace std;
int main()
{
  cout<<"5 % -2 = "<<(5%(-2))<<endl;
  cout<<"-5 % 2 = "<<((-5)%2)<<endl;
  cout<<"-5 % -2 = "<<((-5)%(-2))<<endl;
  cout<<"5 % -3 = "<<(5%(-3))<<endl;
  cout<<"-5 % 3 = "<<((-5)%3)<<endl;
  cout<<"-5 % -3 = "<<((-5)%(-3))<<endl;
  cout<<"5 % -4 = "<<(5%(-4))<<endl;
  cout<<"-5 % 4 = "<<((-5)%4)<<endl;
  cout<<"-5 % -4 = "<<((-5)%(-4))<<endl;
  return 0;
}
[root@VM-0-9-centos YushuTest]# g++ CppTest.cpp -o CppTest
[root@VM-0-9-centos YushuTest]# ./CppTest
5 % -2 = 1
-5 % 2 = -1
-5 % -2 = -1
5 % -3 = 2
-5 % 3 = -2
-5 % -3 = -2
5 % -4 = 1
-5 % 4 = -1
-5 % -4 = -1
Python
[root@VM-0-9-centos YushuTest]# python
Python 2.7.5 (default, Apr  2 2020, 13:16:51)
[GCC 4.8.5 20150623 (Red Hat 4.8.5-39)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> 5 % (-2)
-1
>>> (-5) % 2
1
>>> (-5) % (-2)
-1
>>> 5 % (-3)
-1
>>> (-5) % 3
1
>>> (-5) % (-3)
-2
>>> 5 % (-4)
-3
>>> (-5) % 4
3
>>> (-5) % (-4)
-1
JavaScript

Javascript就直接在浏览器控制台里算的,结果如下

> 5 % (-2)
> 1
> (-5) % 2
> -1
> (-5) % (-2)
> -1
> 5 % (-3)
> 2
> (-5) % 3
> -2
> (-5) % (-3)
> -2
> 5 % (-4)
> 1
> (-5) % 4
> -1
> (-5) % (-4)
> -1

.
.
.
.
.
.


桃花仙人种桃树,又摘桃花换酒钱_

  • 11
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值