Java取模和取余,你真的弄懂了吗?
前言
Java 中常见的取模和取余(求余)计算,在我们日常的很多业务领域都有用到。比如当我们做数据加密时,密码学中不同的加密方案底层会采用不同的模运算来决定其复杂度;做游戏的同学游戏引擎中的取余求最高点;银行金融系统计算中间件开发;随机函数、一致性Hash等等。
问了办公室同样做开发几年的同事,居然对两者区别毫不知晓。转问办公室另一即将科班毕业研究生,对概念也是模糊不清。于是决定总结一下,写下这篇文章。
概念
通常取模运算也叫取余运算,它们返回结果都是余数 .rem 和 mod 唯一的区别在于:
当 x 和 y 的正负号一样的时候,两个函数结果是等同的;当 x 和 y 的符号不同时,rem 函数结果的符号和 x 的一样,而 mod 和 y 一样。
这是由于这两个函数的生成机制不同,rem 函数采用 fix 函数,而 mod 函数采用了 floor 函数(这两个函数是用来取整的,fix 函数向 0 方向舍入,floor 函数向无穷小方向舍入)。 rem(x,y)命令返回的是 x-n.y,如果 y 不等于 0,其中的 n = fix(x./y),而 mod(x,y) 返回的是 x-n.y,当 y 不等于 0 时,n=floor(x./y)
卧槽~ 这是什么鬼 是不是觉得看不懂,下面涛哥用简单的示例来进行介绍,给你整得明明白白的。
Java 示例
我们就创建一个测试类,来进行示例说明
当 x 和 y 的正负号一样的时候,两个函数结果是等同的
package org.taoguoguo.hyper; /**
* @author taoguoguo
* @description ModTest
* @website https://www.cnblogs.com/doondo
* @create 2021-04-19 15:11
*/
public class ModTest {
public static void main(String[] args) {
System.out.println("7对3取余: " + 7%3 );
System.out.println("7对3取模: " + Math.floorMod(7,3)); System.out.println("-7对-3取余: " + (-7) % (-3) );
System.out.println("7对3取模: " + Math.floorMod(-7,-3));
}
}输出结果:
7对3取余: 1
7对3取模: 1
-7对-3取余: -1
7对3取模: -1
当 x 和 y 的符号不同时,rem 函数结果的符号和 x 的一样,而 mod 和 y 一样
package org.taoguoguo.hyper; /**
* @author taoguoguo
* @description ModTest
* @website https://www.cnblogs.com/doondo
* @create 2021-04-19 15:11
* 取余运算结果的符号和 被除数 一致,取模运算结果的符号和 除数 一致
* 取余,遵循尽可能让商向0靠近的原则
* 取模,遵循尽可能让商向负无穷靠近的原则
*/
public class ModTest {
public static void main(String[] args) {
System.out.println("7对-3取余: " + 7%(-3));
System.out.println("7对-3取模: " + Math.floorMod(7,-3)); System.out.println("-7对3取余: " + -7%3);
System.out.println("-7对3取模: " + Math.floorMod(-7,3));
}
}输出结果:
7对-3取余: 1
7对-3取模: -2
-7对3取余: -1
-7对3取模: 2
解析
1.符号相同时: 7/3 = 2.3,产生了两个商2和3
7=3*2+1 或者 7=3*3+(-2)
结论: 7rem3=1 , 7mod3=1
2.符号不同时: 7/(-3)= -2.-3 产生了两个商-2和-3
7=(-3)*(-2)+1 或者 7=(-3)*(-3)+(-2)
结论: 7rem(-3)=1 , 7mod(-3)=(-2)
为什么遵循的是这样的原则?
在matlab中,关于取余和取模是这么定义的:
当y≠0时:
- 取余:rem(x,y)=x-y.*fix(x./y)
- 取模:mod(x,y)=x-y.*floor(x./y)
其中,fix()函数是向0取整,floor()函数是向负无穷取整
以前边的运算为例:
7/(-3)=-2.3,在这个运算中,x为7,y为-3,分别调用fix()和floor()两个函数,得到结果是:
fix(-2.3)=-2
floor(-2.3)=-3
所以,rem(7,-3)=1,mod(7,-3)=-2
总结
- 取余,遵循尽可能让商向0靠近的原则,取模,遵循尽可能让商向负无穷靠近的原则
- 符号相同时,两者不会冲突;符号不同时,两者会产生冲突。
- 取余运算结果的符号和 被除数 一致,取模运算结果的符号和 除数 一致
Java取模和取余,你真的弄懂了吗?的更多相关文章
- C语言fmod()函数:对浮点数取模(求余)
头文件:#include <math.h> fmod() 用来对浮点数进行取模(求余),其原型为: double fmod (double x); 设返回值为 ret,那么 x = ...
- matlab取模与取余
mod函数采用floor,rem函数采用fix函数.那么什么是floor和fix? fix(x):截尾取整.如: >> fix([3.4 , -3.4]) ans = 3 -3 floor ...
- POJ2635——The Embarrassed Cryptographer(高精度取模+筛选取素数)
The Embarrassed Cryptographer DescriptionThe young and very promising cryptographer Odd Even has imp ...
- 取模性质,快速幂,快速乘,gcd和最小公倍数
一.取模运算 取模(取余)运算法则: 1. (a+b)%p=(a%p+b%p)%p; 2.(a-b)%p=(a%p-b%p)%p; 3.(a*b)%p=(a%p * b%p)%p; 4.(a^b)%p ...
- fmod()函数 (对浮点数取模)
头文件:#include <math.h> fmod() 用来对浮点数进行取模(求余),其原型为: double fmod (double x); 设返回值为 ret,那么 x = ...
- C++负数类型转换,-1对256取模
最近在读C++ primer的时候,发现p32上写道:当我们赋给无符号类型一个超出它表示范围的值时,结果是初始值对无符号类型表示数值总数取模后的余数.因此,把-1赋值给8比特大小的unsigned c ...
- HDU1013,1163 ,2035九余数定理 快速幂取模
1.HDU1013求一个positive integer的digital root,即不停的求数位和,直到数位和为一位数即为数根. 一开始,以为integer嘛,指整型就行吧= =(too young ...
- HPU 1471:又是斐波那契数列??(大数取模)
1471: 又是斐波那契数列?? 时间限制: 1 Sec 内存限制: 128 MB 提交: 278 解决: 27 统计 题目描述 大家都知道斐波那契数列吧?斐波那契数列的定义是这样的: f0 = 0; ...
- 为什么对1e9 + 7取模
在刷题的时候,很多题目答案都要求结果对1e9 + 7取模 刚开始我非常不理解,为什么要取模,取模难道结果不会变吗? 答案是结果会变,但因为原本需要得出的答案可能超出int64的范围,比如他叫你计算50 ...
- java中求余%与取模floorMod的区别
初学java的时候接触的%这个符号 百分号? 求余? 取模? 我只知道不是百分号,好像是求余,听别人那叫求模运算符,跟求余一样,于是我便信了. 思考之后开始迷糊,然后经过多次考证得到以下结论. 首先, ...
随机推荐
- 缺氧debu模式
OxygenNotIncluded_Data(E:\SteamLibrary\steamapps\common\OxygenNotIncluded\OxygenNotIncluded_Data) 文件 ...
- 【Python】基于动态规划和K聚类的彩色图片压缩算法
引言 当想要压缩一张彩色图像时,彩色图像通常由数百万个颜色值组成,每个颜色值都由红.绿.蓝三个分量组成.因此,如果我们直接对图像的每个像素进行编码,会导致非常大的数据量.为了减少数据量,我们可以尝试减 ...
- input标签 手机端数字键盘
要一点击提起数字键盘,安卓只要设置input的类型是number或tel, ios 需要 pattern="number"可以直接打开搜狗输入法的数字键盘,可以输入.和数字如果只能 ...
- 分布式事务的概念和解决方案Seate
引入分布式事务: 在电商系统中,扣减库存与保存订单是在两个服务中存在的,如果扣减库存后订单保存失败了是不会回滚的,这样就会造成数据不一致的情况,这其实就是我们所说的分布式事务的问题,接下来我们来学习分 ...
- Unity无法安装Entities 1.2.0 Package的解决方法
会出现如下的错误提示: 本质原因是国内版的Unity使用了自己的Package加速CDN:packages.unity.cn,而不是官方的packages.unity.com.而这个CDN更新了Ent ...
- 原创软件 | 系统服务工具箱原创软件(587KB)--基于aardio开发的第一个程序
1 系统服务工具箱简介 该软件是我使用aardio开发的第一个程序,它集成了多个系统常用的快捷键,无需记住各种命令就能快捷使用cmd管理员.计算机管理.控制面板.组策略.注册表.服务.任务管理.卸载程 ...
- SQL_left join 和from 两个表的区别
一个是普通的联接,结果中的记录在两个表中都有.一个是左外联接,结果中的记录在A表中存在,B表中不一定有.相当于a表为主体表,b为辅助表. 例子: mysql> select * from a;+ ...
- Hyperledger Fabric 2.x 环境搭建
一.说明 区块链网络的核心是分布式账本,在这个账本中记录了网络中发生的所有交易信息. Hyperledger Fabric是一个是开源的,企业级的,带权限的分布式账本解决方案的平台.Hyperledg ...
- 【Dos-BatchPrograming】03
--1.AT 计划任务 Microsoft Windows [版本 10.0.19041.746] (c) 2020 Microsoft Corporation. 保留所有权利. C:\Users\A ...
- 【IDEA】使用Maven骨架创建JavaWeb项目
IDEA版本:2020.1 骨架选项名称: org.apache.maven.archetypes:maven-archetype-webapp 本项目的Maven坐标设置: 设置优先从本地获取骨架: ...