Java取模和取余,你真的弄懂了嗎?


前言

Java 中常見的取模和取余(求余)計算,在我們日常的很多業務領域都有用到。比如當我們做數據加密時,密碼學中不同的加密方案底層會采用不同的模運算來決定其復雜度;做游戲的同學游戲引擎中的取余求最高點;銀行金融系統計算中間件開發;隨機函數、一致性Hash等等。

問了辦公室同樣做開發幾年的同事,居然對兩者區別毫不知曉。轉問辦公室另一即將科班畢業研究生,對概念也是模糊不清。於是決定總結一下,寫下這篇文章。

概念

通常取模運算也叫取余運算,它們返回結果都是余數 .remmod 唯一的區別在於:

當 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

總結

  1. 取余,遵循盡可能讓商向0靠近的原則,取模,遵循盡可能讓商向負無窮靠近的原則
  2. 符號相同時,兩者不會沖突;符號不同時,兩者會產生沖突。
  3. 取余運算結果的符號和 被除數 一致,取模運算結果的符號和 除數 一致


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM