Java取模和取余,你真的弄懂了嗎?
前言
Java 中常見的取模和取余(求余)計算,在我們?nèi)粘5暮芏鄻I(yè)務(wù)領(lǐng)域都有用到。比如當(dāng)我們做數(shù)據(jù)加密時,密碼學(xué)中不同的加密方案底層會采用不同的模運(yùn)算來決定其復(fù)雜度;做游戲的同學(xué)游戲引擎中的取余求最高點(diǎn);銀行金融系統(tǒng)計算中間件開發(fā);隨機(jī)函數(shù)、一致性Hash等等。
問了辦公室同樣做開發(fā)幾年的同事,居然對兩者區(qū)別毫不知曉。轉(zhuǎn)問辦公室另一即將科班畢業(yè)研究生,對概念也是模糊不清。于是決定總結(jié)一下,寫下這篇文章。
概念
通常取模運(yùn)算也叫取余運(yùn)算,它們返回結(jié)果都是余數(shù) .rem 和 mod 唯一的區(qū)別在于:
當(dāng) x 和 y 的正負(fù)號一樣的時候,兩個函數(shù)結(jié)果是等同的;當(dāng) x 和 y 的符號不同時,rem 函數(shù)結(jié)果的符號和 x 的一樣,而 mod 和 y 一樣。
這是由于這兩個函數(shù)的生成機(jī)制不同,rem 函數(shù)采用 fix 函數(shù),而 mod 函數(shù)采用了 floor 函數(shù)(這兩個函數(shù)是用來取整的,fix 函數(shù)向 0 方向舍入,floor 函數(shù)向無窮小方向舍入)。 rem(x,y)命令返回的是 x-n.y,如果 y 不等于 0,其中的 n = fix(x./y),而 mod(x,y) 返回的是 x-n.y,當(dāng) y 不等于 0 時,n=floor(x./y)
臥槽~ 這是什么鬼 是不是覺得看不懂,下面濤哥用簡單的示例來進(jìn)行介紹,給你整得明明白白的。
Java 示例
我們就創(chuàng)建一個測試類,來進(jìn)行示例說明
-
當(dāng) x 和 y 的正負(fù)號一樣的時候,兩個函數(shù)結(jié)果是等同的
package org.taoguoguo.hyper; /** * @author taoguoguo * @description ModTest * @website http://www.rzrgm.cn/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)); } }輸出結(jié)果:
7對3取余: 1 7對3取模: 1 -7對-3取余: -1 7對3取模: -1 -
當(dāng) x 和 y 的符號不同時,rem 函數(shù)結(jié)果的符號和 x 的一樣,而 mod 和 y 一樣
package org.taoguoguo.hyper; /** * @author taoguoguo * @description ModTest * @website http://www.rzrgm.cn/doondo * @create 2021-04-19 15:11 * 取余運(yùn)算結(jié)果的符號和 被除數(shù) 一致,取模運(yùn)算結(jié)果的符號和 除數(shù) 一致 * 取余,遵循盡可能讓商向0靠近的原則 * 取模,遵循盡可能讓商向負(fù)無窮靠近的原則 */ 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)); } }輸出結(jié)果:
7對-3取余: 1 7對-3取模: -2 -7對3取余: -1 -7對3取模: 2
解析
1.符號相同時: 7/3 = 2.3,產(chǎn)生了兩個商2和3
7=3*2+1 或者 7=3*3+(-2)
結(jié)論: 7rem3=1 , 7mod3=1
2.符號不同時: 7/(-3)= -2.-3 產(chǎn)生了兩個商-2和-3
7=(-3)*(-2)+1 或者 7=(-3)*(-3)+(-2)
結(jié)論: 7rem(-3)=1 , 7mod(-3)=(-2)
為什么遵循的是這樣的原則?
在matlab中,關(guān)于取余和取模是這么定義的:
-
當(dāng)y≠0時:
- 取余:rem(x,y)=x-y.*fix(x./y)
- 取模:mod(x,y)=x-y.*floor(x./y)
其中,fix()函數(shù)是向0取整,floor()函數(shù)是向負(fù)無窮取整
以前邊的運(yùn)算為例:
7/(-3)=-2.3,在這個運(yùn)算中,x為7,y為-3,分別調(diào)用fix()和floor()兩個函數(shù),得到結(jié)果是:
fix(-2.3)=-2
floor(-2.3)=-3
所以,rem(7,-3)=1,mod(7,-3)=-2
總結(jié)
- 取余,遵循盡可能讓商向0靠近的原則,取模,遵循盡可能讓商向負(fù)無窮靠近的原則
- 符號相同時,兩者不會沖突;符號不同時,兩者會產(chǎn)生沖突。
- 取余運(yùn)算結(jié)果的符號和 被除數(shù) 一致,取模運(yùn)算結(jié)果的符號和 除數(shù) 一致

浙公網(wǎng)安備 33010602011771號