深入學習java原始碼之Math.floor()與 Math.rint()
深入學習java原始碼之Math.floor()與 Math.rint()
java中有三種移位運算子
<< : 左移運算子,num << 1,相當於num乘以2
>> : 右移運算子,num >> 1,相當於num除以2
>>> : 無符號右移,忽略符號位,空位都以0補齊
二進位制最左端的數字為符號位,0代表正,1代表負,這裡先介紹幾個概念
邏輯左移=算術左移:高位溢位,低位補0
邏輯右移:低位溢位,高位補0
算術右移:低位溢位,高位用符號位的值補
比如一個有符號位的8位二進位制數10101010,[]是新增的數字
邏輯左移一位:0101010[0]
邏輯左移兩位:101010[00]
算術左移一位:0101010[0]
算術左移兩位:101010[00]
邏輯右移一位:[0]1010101
邏輯右移兩位:[00]101010
算術右移一位:[1]1010101
算術右移兩位:[11]101010
算術左移和算術右移主要用來進行有符號數的倍增、減半
邏輯左移和邏輯右移主要用來進行無符號數的倍增、減半
(Java中是沒有無符號資料型別的,C和C++中有)
java中的邏輯運算子
Java中&叫做按位與,&&叫做短路與,它們的區別是:
& 既是位運算子又是邏輯運算子,&的兩側可以是int,也可以是boolean表示式,當&兩側是int時,要先把運算子兩側的數轉化為二進位制數再進行運算,而短路與(&&)的兩側要求必須是布林表示式。
12&5 的值是多少?答:12轉成二進位制數是1100(前四位省略了),5轉成二進位制數是0101,則運算後的結果為0100即4 這是兩側為數值時;
若 int i = 2,j = 4;則(++i=2)&(j++=4)的結果為false,其過程是這樣的:先判斷++i=2是否成立,這裡當然是不成立了(3 == 2),但是程式還會繼續判斷下一個表示式是否成立,j++=4 ,該表示式是成立的,但是&運算子要求運算子兩側的值都為真,結果才為真,所以(++i=2)&(j++=4)的結果為 false 注意 :&為真的條件是兩側表示式都為真,但是即使我們判斷出左側表示式的值為false,程式也還是要繼續執行去判斷右側的表示式值的真假
若 int i = 2,j = 4;則(++i=2)&&(j++=4)的結果為false,其過程基本上和上面的是相同的,但是若左側表示式的值為false時,程式則不會繼續判斷右側表示式的真假了,短路與中,短路這個詞大概也就是這個意思吧
Java中‘|’與‘||’的區別
int i=0;
if(3>2 || (i++)>1) i=i+1;
System.out.println(i);
這段程式會打印出1,而不是打印出2。
因為在if的條件判斷中,程式先判斷第一個表示式3>2是否成立,結果3>2為真,那麼按照邏輯來說,無論後面一個表示式(i++)>1是否成立,整個或表示式肯定為真,因此程式就不去執行判斷後面一個表示式即(i++)>1了,所以這裡i並沒有自增1。然後程式執行到i=i+1,於是i變為1。最後打印出1。
int i=0;
if(3>2 | (i++)>1) i=i+1;
System.out.println(i);
如果換做這樣寫,那麼就是打印出2了,因為無論第一個條件3>2是否為真,程式都會去執行判斷第二個條件表示式,因此i++這個自增是會被執行的,再加上if內的i=i+1,所以最終i=2。
Modifier and Type | Method and Description |
---|---|
static double |
abs(double a) 返回值為 |
static float |
abs(float a) 返回 |
static int |
abs(int a) 返回值為 |
static long |
abs(long a) 返回值為 |
static double |
ceil(double a) 返回大於或等於引數的最小(最接近負無窮大) |
static double |
copySign(double magnitude, double sign) 使用第二個浮點引數的符號返回第一個浮點引數。 |
static float |
copySign(float magnitude, float sign) 使用第二個浮點引數的符號返回第一個浮點引數。 |
static double |
floor(double a) 返回小於或等於引數的最大(最接近正無窮大) |
static int |
getExponent(double d) 返回a的表示中使用的無偏指數 |
static int |
getExponent(float f) 返回a的表示中使用的無偏指數 |
static double |
rint(double a) 返回與引數最接近值的 |
java原始碼
public final class Math {
private Math() {}
public static double ceil(double a) {
return StrictMath.ceil(a); // default impl. delegates to StrictMath
}
public static double floor(double a) {
return StrictMath.floor(a); // default impl. delegates to StrictMath
}
public static double rint(double a) {
return StrictMath.rint(a); // default impl. delegates to StrictMath
}
public static int getExponent(float f) {
/*
* Bitwise convert f to integer, mask out exponent bits, shift
* to the right and then subtract out float's bias adjust to
* get true exponent value
*/
return ((Float.floatToRawIntBits(f) & FloatConsts.EXP_BIT_MASK) >>
(FloatConsts.SIGNIFICAND_WIDTH - 1)) - FloatConsts.EXP_BIAS;
}
public static double copySign(double magnitude, double sign) {
return Double.longBitsToDouble((Double.doubleToRawLongBits(sign) &
(DoubleConsts.SIGN_BIT_MASK)) |
(Double.doubleToRawLongBits(magnitude) &
(DoubleConsts.EXP_BIT_MASK |
DoubleConsts.SIGNIF_BIT_MASK)));
}
public static float copySign(float magnitude, float sign) {
return Float.intBitsToFloat((Float.floatToRawIntBits(sign) &
(FloatConsts.SIGN_BIT_MASK)) |
(Float.floatToRawIntBits(magnitude) &
(FloatConsts.EXP_BIT_MASK |
FloatConsts.SIGNIF_BIT_MASK)));
}
public static int abs(int a) {
return (a < 0) ? -a : a;
}
public static long abs(long a) {
return (a < 0) ? -a : a;
}
public static float abs(float a) {
return (a <= 0.0F) ? 0.0F - a : a;
}
public static double abs(double a) {
return (a <= 0.0D) ? 0.0D - a : a;
}
}
public final class StrictMath {
private StrictMath() {}
public static double ceil(double a) {
return floorOrCeil(a, -0.0, 1.0, 1.0);
}
public static double floor(double a) {
return floorOrCeil(a, -1.0, 0.0, -1.0);
}
private static double floorOrCeil(double a,
double negativeBoundary,
double positiveBoundary,
double sign) {
int exponent = Math.getExponent(a);
if (exponent < 0) {
/*
* Absolute value of argument is less than 1.
* floorOrceil(-0.0) => -0.0
* floorOrceil(+0.0) => +0.0
*/
return ((a == 0.0) ? a :
( (a < 0.0) ? negativeBoundary : positiveBoundary) );
} else if (exponent >= 52) {
/*
* Infinity, NaN, or a value so large it must be integral.
*/
return a;
}
// Else the argument is either an integral value already XOR it
// has to be rounded to one.
assert exponent >= 0 && exponent <= 51;
long doppel = Double.doubleToRawLongBits(a);
long mask = DoubleConsts.SIGNIF_BIT_MASK >> exponent;
if ( (mask & doppel) == 0L )
return a; // integral value
else {
double result = Double.longBitsToDouble(doppel & (~mask));
if (sign*a > 0.0)
result = result + sign;
return result;
}
}
public static double rint(double a) {
double twoToThe52 = (double)(1L << 52); // 2^52
double sign = Math.copySign(1.0, a); // preserve sign info
a = Math.abs(a);
if (a < twoToThe52) { // E_min <= ilogb(a) <= 51
a = ((twoToThe52 + a ) - twoToThe52);
}
return sign * a; // restore original sign
}
public static double copySign(double magnitude, double sign) {
return Math.copySign(magnitude, (Double.isNaN(sign)?1.0d:sign));
}
public static float copySign(float magnitude, float sign) {
return Math.copySign(magnitude, (Float.isNaN(sign)?1.0f:sign));
}
}