zl程序教程

您现在的位置是:首页 >  后端

当前栏目

C++、C++-OpenCV、Python、Python-Numpy、MATLAB的除法取余(余数)方法总结

2023-09-11 14:15:39 时间

C++、Python、MATLAB的除法取余方法总结对比。

既然本文的研究对象是余数,那么显然是两个整数之间的除法,这才是我们主要的运用场景,这一点大家要明白。当然从文中我们也可以看出,Python内置函数divmod()是支持浮点数取余运算的,MATLAB的函数mod()和rem()也是支持浮点数的取余运算的。

01-C++中除法取余运算

在C++中有两种方法实现整数除法的取余。
一是用取余运算符 % 来实现整数除法的取余;
二是用标准库math中的函数fmod实现。

下面分别介绍:
方法一:用取余运算符 % 来实现整数除法的取余。

  • 如果被除数和除数都是正数,那么余数为正数或0
  • 如果被除数和除数都是负数,那么余数为负数或0
  • 如果被除数为正数,而除数是负数,那么余数为正数或0
  • 如果被除数为负数,而除数是正数,那么余数为负数或0

示例代码如下:

#include <iostream>

using namespace std;

int main() 
{
	//被除数和除数都为正数的情况
	int a1 = 13, b1 = 5;
	int c1;
	c1 = a1%b1;
	cout << "c1的值为:" << c1 << endl;

	//被除数和除数都为负数的情况
	int a2 = -14, b2 = -5;
	int c2;
	c2 = a2%b2;
	cout << "c2的值为:" << c2 << endl;

	//被除数为正数,除数为负数的情况
	int a3 = 14, b3 = -5;
	int c3;
	c3 = a3%b3;
	cout << "c3的值为:" << c3 << endl;

	//被除数为负数,除数为正数的情况
	int a4 = -14, b4 = 5;
	int c4;
	c4 = a4%b4;
	cout << "c4的值为:" << c4 << endl;


	return 0;
}

运行结果如下:
在这里插入图片描述
方法二:用标准库math中的函数fmod()实现
fmod()的原型如下:

double fmod(double X, double Y);

示例代码如下:

#include <iostream>
#include <math.h>

using namespace std;

int main() 
{

	double x1 = 9, y1 = 5;
	double z1;
	z1 = fmod(x1, y1);
	cout << "z1的值为:" << z1 << endl;

	double x2 = -9, y2 = -5;
	double z2;
	z2 = fmod(x2, y2);
	cout << "z2的值为:" << z2 << endl;

	double x3 = -9, y3 = 5;
	double z3;
	z3 = fmod(x3, y3);
	cout << "z3的值为:" << z3 << endl;

	double x4 = 9, y4 = -5;
	double z4;
	z4 = fmod(x4, y4);
	cout << "z4的值为:" << z4 << endl;

	double x5 = 9, y5 = 5.1;
	double z5;
	z5 = fmod(x5, y5);
	cout << "z5的值为:" << z5 << endl;

	double x6 = 9.2, y6 = 5.1;
	double z6;
	z6 = fmod(x6, y6);
	cout << "z6的值为:" << z6 << endl;

	double x7 = 9.3, y7 = 5;
	double z7;
	z7 = fmod(x7, y7);
	cout << "z7的值为:" << z7 << endl;

	return 0;
}

运行结果如下:
在这里插入图片描述
从上面的运行结果可以看出,函数fmod()的余数结果是与被除数相同的,所以它应该与MATLAB中的函数rem()的运算是一样的。

01-附1-C++中的OpenCV库的Mat对象中各元素除法的取余操作

关于这个操作,这个目前博主没有发现相关函数,似乎只能让每个元素与每个元素单独作取余运算。
或者也可以将矩阵运算的真除结果与向下取整的结果相减实现。

02-Python中的除法取余运算

Python中的除法取余运算有三种,一种是用运算符%实现,第二种是用内置函数divmod()实现,下面分别举例,第三种用标准库math中的函数fmod()和函数remainder()实现。
第一种:用运算符%实现

# 被除数和除数都是正数的情况
a1 = 13
b1 = 5
c1 = a1 % b1

# 被除数和除数都是负数的情况
a2 = -14
b2 = -5
c2 = a2 % b2

# 被除数是正数,除数是负数的情况
a3 = 14
b3 = -5
c3 = a3 % b3

# 被除数是负数,除数是正数的情况
a4 = -14
b4 = 5
c4 = a4 % b4

# 验证被除数是正数,除数是负数时,结果是否为-1
a5 = 23
b5 = -6
c5 = a5 % b5

# 验证被除数是负数,除数是正数时,结果是否为+1
a6 = -23
b6 = 6
c6 = a6 % b6

# 验证被除数是正数,除数是负数且能整除时,结果是否为0
a7 = -24
b7 = 6
c7 = a7 % b7

# 验证被除数是负数,除数是正数且能整除时,结果是否为0
a8 = -24
b8 = 6
c8 = a8 % b8

运算结果如下:
在这里插入图片描述

从上面的运算结果可以看出:

  • 如果被除数和除数都是正数,那么余数为正数或0
  • 如果被除数和除数都是负数,那么余数为负数或0
  • 如果被除数为正数,而除数是负数,那么余数为-1或0
  • 如果被除数为负数,而除数是正数,那么余数为+1或0

那么,我们可以总结出,实际上余数的符号和除数的符号相同。

第二种:用内置函数divmod()实现
函数divmod()的语法如下:

divmod(a, b)

如果参数 a 与 参数 b 都是整数,函数返回的结果相当于 (a // b, a % b)。
如果其中一个参数为浮点数时,函数返回的结果相当于 (q, a % b),q 通常是 math.floor(a / b),函数会使 q * b + a % b近可能接近于a。
余数的符号与除数相同。
注意:当被除数和除数是异号的整数时,余数只有三个值,当能整除时,余数为0;当不能整除时,若除数为负数,余数为-1,若除数为正数,余数为1。

示例代码如下:

# 被除数和除数都是正数的情况
a1 = 13
b1 = 5
c01 = divmod(a1, b1)

# 被除数和除数都是负数的情况
a2 = -14
b2 = -5
c02 = divmod(a2, b2)

# 被除数是正数,除数是负数的情况
a3 = 14
b3 = -5
c03 = divmod(a3, b3)

# 被除数是负数,除数是正数的情况
a4 = -14
b4 = 5
c04 = divmod(a4, b4)

# 验证被除数是正数,除数是负数时,结果是否为-1
a5 = 23
b5 = -6
c05 = divmod(a5, b5)

# 验证被除数是负数,除数是正数时,结果是否为+1
a6 = -23
b6 = 6
c06 = divmod(a6, b6)

# 验证被除数是正数,除数是负数且能整除时,结果是否为0
a7 = -24
b7 = 6
c07 = divmod(a7, b7)

# 验证被除数是负数,除数是正数且能整除时,结果是否为0
a8 = -24
b8 = 6
c08 = divmod(a8, b8)

# 被除数是正的浮点数,除数是正的整数的情况
a9 = 5.3
b9 = 2
c09 = divmod(a9, b9)

# 被除数是负的浮点数,除数是负的整数的情况
a10 = -5.3
b10 = -2
c10 = divmod(a10, b10)

# 被除数是负的浮点数,除数是正的整数的情况
a11 = -5.3
b11 = 2
c11 = divmod(a11, b11)

# 被除数是正的浮点数,除数是负的整数的情况
a12 = 5.3
b12 = -2
c12 = divmod(a12, b12)

# 被除数是整数,除数是浮点数的情况
a13 = 6
b13 = -2.2
c13 = divmod(a13, b13)

# 被除数是浮点数,除数也是浮点数的情况
a14 = 6.8
b14 = -2.2
c14 = divmod(a14, b14)

运行结果如下:
在这里插入图片描述
方法三的第1个函数:使用math库中的函数fmod(x, y)作取余运算
Python-math库中的函数fmod(x, y)与C++标准库math中的函数fmod()用法基本一样,这样就不给示例代码了。

方法三的第2个函数:使用math库中的函数remainder(x, y)作取余运算
这个的详细介绍见博文 https://blog.csdn.net/wenhao_ir/article/details/125607783的第2-21点。这个要特别注意,当被除数和除数都为正数时,余数也有可能为负哦。

02-附1-Numpy库中的ndarray对象的取余运算

Numpy库中的ndarray对象的取余运算有三种方法,详情见博文https://blog.csdn.net/wenhao_ir/article/details/125226556的第10点。

03-MATLAB的取余运算

在MATLAB中可以用函数mod()和rem()实现除法的取余运算。
二者的语法是一样的,都是第一个参数为被除数,第二个参数为除数。
语法分别如下:

b = mod(a,m)
r = rem(a,b)

函数mod()和rem()的区别:

二者的主要区别在于计数余数的表达式不一样:

函数mod()计算余数的表达式为: b = a - m.*floor(a./m),函数floor()为朝负无穷方向的四舍五入,函数floor()的详情可参考链接:https://ww2.mathworks.cn/help/releases/R2019b/matlab/ref/floor.html

函数rem()计算余数的表达式为:r = a - b.*fix(a./b),函数fix()为朝坐标轴零点的四舍五入,函数fix()详情可参考链接:https://ww2.mathworks.cn/help/releases/R2019b/matlab/ref/fix.html

由以上计算式可以生成这样的结果:mod 函数生成一个为零或与除数具有相同符号的结果。rem 函数生成一个为零或与被除数具有相同符号的结果。问:为什么会有这样的结果,你根据函数floor()和函数fix()的定义再带入实际的例子就明白了。

另一个差别是当除数为零时的约定。mod 函数遵从 mod(a,0) 返回 a 的约定,而 rem 函数遵从 rem(a,0) 返回 NaN 的约定。

两个结果都有其各自的用途。例如,在进行信号处理时,mod 函数可在周期信号上下文中使用,因为其输出是周期性的(周期等于除数,而mod的取余结果的符号与除数相同)。
示例代码如下:

a1 = mod(9,4);
a2 = rem(9,4);

b1 = mod(-9,4);
b2 = rem(-9,4);

c1 = mod(-9.3,4)
c2 = mod(-9.3,4)

运行结果如下:
在这里插入图片描述
由以上结果可以看出,当被除数为除数都是正数时,两个函数的结果是一样的,但是当被除数和除数符号不一样时,结果就因计算过程中舍入方式的不同而呈现不同的结果了。