java求余的技巧匯總
背景
傳說(shuō)里玉皇大帝派龍王馬上降雨到共光一帶,龍王接到玉皇大帝命令,立馬從海上調(diào)水,跑去共光施云布雨,但粗心又著急的龍王不小心把海里的鯨魚(yú)隨著雨水一起降落在了共光,龍王怕玉皇大帝責(zé)怪,靈機(jī)一動(dòng)便聲稱他是派魚(yú)到共光,希望百姓可以年年有余,并請(qǐng)求玉皇大帝將這條魚(yú)任命為魚(yú)神,保佑人間太平可以年年有余。

年年有余
java 求余操作初階
java中也有余的規(guī)范【jls-15.17.3】,廢話不說(shuō),直接上代碼,從中我們可以學(xué)到很多技巧:
例1:
int a = 5%3; // 2
int b = 5/3; // 1
System.out.println("5%3 produces " + a +" (note that 5/3 produces " + b + ")");
相信大多數(shù)人都知道結(jié)果了:
5%3 produces 2 (note that 5/3 produces 1)
java 求余操作中階
我們知道,正數(shù)不僅僅有正整數(shù)還有負(fù)整數(shù),那么負(fù)數(shù)的情況下,會(huì)出現(xiàn)什么變化呢?
例2:
int c = 5%(-3); // 2
int d = 5/(-3); // -1
System.out.println("5%(-3) produces " + c +" (note that 5/(-3) produces " + d + ")");
int e = (-5)%3; // -2
int f = (-5)/3; // -1
System.out.println("(-5)%3 produces " + e +" (note that (-5)/3 produces " + f + ")");
int g = (-5)%(-3); // -2
int h = (-5)/(-3); // 1
System.out.println("(-5)%(-3) produces " + g +" (note that (-5)/(-3) produces " + h + ")");
能完全正確得到結(jié)果的就很少了吧?
5%(-3) produces 2 (note that 5/(-3) produces -1)
(-5)%3 produces -2 (note that (-5)/3 produces -1)
(-5)%(-3) produces -2 (note that (-5)/(-3) produces 1)
為什么求余的結(jié)果是這樣的呢?jls-15.17.3規(guī)范告訴我們:
The binary % operator is said to yield the remainder of its operands from an implied division; the left-hand operand is the dividend and the right-hand operand is the divisor.
It follows from this rule that the result of the remainder operation can be negative only if the dividend is negative, and can be positive only if the dividend is positive. Moreover, the magnitude of the result is always less than the magnitude of the divisor.
注意:求余的正負(fù)數(shù)給dividend(左邊操作數(shù))的符號(hào)位一致!
java 求余操作高階
java求余操作不但支持整數(shù)還支持浮點(diǎn)數(shù)
class Test2 {
public static void main(String[] args) {
double a = 5.0%3.0; // 2.0
System.out.println("5.0%3.0 produces " + a);
double b = 5.0%(-3.0); // 2.0
System.out.println("5.0%(-3.0) produces " + b);
double c = (-5.0)%3.0; // -2.0
System.out.println("(-5.0)%3.0 produces " + c);
double d = (-5.0)%(-3.0); // -2.0
System.out.println("(-5.0)%(-3.0) produces " + d);
}
}
相信很多人可以根據(jù)整型的規(guī)則,得出正確的結(jié)果
5.0%3.0 produces 2.0
5.0%(-3.0) produces 2.0
(-5.0)%3.0 produces -2.0
(-5.0)%(-3.0) produces -2.0
補(bǔ)充一下,浮點(diǎn)型的求余有一些特殊的規(guī)則:
The result of a floating-point remainder operation as computed by the % operator is not the same as that produced by the remainder operation defined by IEEE 754. The IEEE 754 remainder operation computes the remainder from a rounding division, not a truncating division, and so its behavior is not analogous to that of the usual integer remainder operator. Instead, the Java programming language defines % on floating-point operations to behave in a manner analogous to that of the integer remainder operator; this may be compared with the C library function fmod. The IEEE 754 remainder operation may be computed by the library routine Math.IEEEremainder.
The result of a floating-point remainder operation is determined by the rules of IEEE 754 arithmetic:
If either operand is NaN, the result is NaN.
If the result is not NaN, the sign of the result equals the sign of the dividend.
If the dividend is an infinity, or the divisor is a zero, or both, the result is NaN.
If the dividend is finite and the divisor is an infinity, the result equals the dividend.
If the dividend is a zero and the divisor is finite, the result equals the dividend.
In the remaining cases, where neither an infinity, nor a zero, nor NaN is involved, the floating-point remainder r from the division of a dividend n by a divisor d is defined by the mathematical relation r = n - (d ⋅ q) where q is an integer that is negative only if n/d is negative and positive only if n/d is positive, and whose magnitude is as large as possible without exceeding the magnitude of the true mathematical quotient of n and d.
Evaluation of a floating-point remainder operator % never throws a run-time exception, even if the right-hand operand is zero. Overflow, underflow, or loss of precision cannot occur.
java 求余操作骨灰級(jí)
學(xué)到這里,或許有人沾沾自喜,我都掌握了求余的所有規(guī)則,看來(lái)需要給你潑潑冷水:
public static void main(String[] args) {
final int MODULUS = 3;
int[] histogram = new int[MODULUS];
// Iterate over all ints (Idiom from Puzzle 26)
int i = Integer.MIN_VALUE;
do {
histogram[Math.abs(i) % MODULUS]++;
} while (i++ != Integer.MAX_VALUE);
for (int j = 0; j < MODULUS; j++)
System.out.println(histogram[j] + " ");
}
這個(gè)程序會(huì)打印什么?有人經(jīng)過(guò)繁瑣復(fù)雜的算出一個(gè)結(jié)果:
1431655765 1431655766 1431655765
但其實(shí),上述程序運(yùn)行報(bào)錯(cuò):
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: -2
at com.java.puzzlers.ModTest.main(ModTest.java:11)
為什么數(shù)組會(huì)出現(xiàn)索引 -2?奇怪吧?要回答這個(gè)問(wèn)題,我們必須要去看看Math.abs 的文檔
/**
* Returns the absolute value of an {@code int} value.
* If the argument is not negative, the argument is returned.
* If the argument is negative, the negation of the argument is returned.
*
* <p>Note that if the argument is equal to the value of
* {@link Integer#MIN_VALUE}, the most negative representable
* {@code int} value, the result is that same value, which is
* negative.
*
* @param a the argument whose absolute value is to be determined
* @return the absolute value of the argument.
*/
public static int abs(int a) {
return (a < 0) ? -a : a;
}
特意說(shuō)明,如果是Integer#MIN_VALUE,返回負(fù)數(shù)
java里有很多小技巧,需要我們勤翻api和jsl,多學(xué)習(xí)多練習(xí)。
參考資料:
【1】https://baike.baidu.com/item/%E5%B9%B4%E5%B9%B4%E6%9C%89%E4%BD%99/7625174?fr=aladdin
【2】https://docs.oracle.com/javase/specs/jls/se12/html/jls-15.html#jls-15.17.3
【3】java解惑
總結(jié)
以上就是我在處理客戶端真實(shí)IP的方法,希望本文的內(nèi)容對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,謝謝大家對(duì)腳本之家的支持。
相關(guān)文章
MyBatis-Plus中如何配置加密功能(使用AES算法)
本文將詳細(xì)介紹如何實(shí)現(xiàn) MyBatis-Plus 中的配置加密功能,并給出相應(yīng)的代碼示例,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2025-03-03
Java如何基于ProcessBuilder類調(diào)用外部程序
這篇文章主要介紹了Java如何基于ProcessBuilder類調(diào)用外部程序,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-01-01
Java基礎(chǔ)之線程鎖相關(guān)知識(shí)總結(jié)
今天給大家?guī)?lái)的是關(guān)于Java線程的相關(guān)知識(shí),文章圍繞著Java線程鎖展開(kāi),文中有非常詳細(xì)的介紹及代碼示例,需要的朋友可以參考下2021-06-06
spring security在分布式項(xiàng)目下的配置方法(案例詳解)
這篇文章主要介紹了spring security在分布式項(xiàng)目下的配置方法,本文通過(guò)一個(gè)項(xiàng)目案例給大家詳細(xì)介紹,通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-10-10
maven打包成第三方j(luò)ar包且把pom依賴包打入進(jìn)來(lái)的方法
這篇文章主要介紹了maven打包成第三方j(luò)ar包且把pom依賴包打入進(jìn)來(lái)的方法,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2018-11-11
mybatis.type-aliases-package的作用及用法說(shuō)明
這篇文章主要介紹了mybatis.type-aliases-package的作用及用法說(shuō)明,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-01-01

