深入學習java原始碼之Math.addExact()與 Math.multiplyExact()
深入學習java原始碼之Math.addExact()與 Math.multiplyExact()
^運算子
或的運算子,其運算規則是:
兩個運算元的位中,相同則結果為0,不同則結果為1。
int i = 15, j = 2
執行結果是:i ^ j = 13.
分析上面程式,i=15轉成二進位制是1111,j=2轉成二進位制是0010,根據異或的運算規則得到的是1101,轉成十進位制就是13.
K+1個數,其中有2k個相同,需要找出不相同的那個數,比如:2、3、4、4、3、5、6、6、5。
int[] array = {2,3,4,4,3,5,6,6,5}; int v = 0; for (int i = 0;i < array.length;i++) { v ^= array[i]; System.out.println("只出現一次的數是:" + v); } 只出現一次的數是2.
基本資料型別的加減乘除運算
加法
int a = 10;
long b = 35;
float c = 36.95f;
double d = 18.04;
減法
long a = 300;
int b = 18;
float c = 128.7f;
double d = 53.31;
float jian = (float)(a - b - c - (double)d);
乘法
int a = 1;
long b = 1000000;
float c = 0.000001f;
double d = 99.99;
除法
int a = 1000; long b = 1000000; float c = 0.001f; double d = 99.99; float chu = (float)((double)d/(a/b/c));
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 int |
addExact(int x, int y) 返回其引數的總和,如果結果溢位int,則丟擲 |
static long |
addExact(long x, long y) 返回其引數的總和,如果結果溢位long,則丟擲 |
static int |
decrementExact(int a) 返回一個遞減1的引數,如果結果溢位int,則 |
static long |
decrementExact(long a) 將返回的引數遞減1,如果結果溢位long,則 |
static double |
floor(double a) 返回小於或等於引數的最大(最接近正無窮大) |
static int |
floorDiv(int x, int y) 返回小於或等於代數商的最大(最接近正無窮大) |
static long |
floorDiv(long x, long y) 返回小於或等於代數商的最大(最接近正無窮大) |
static int |
floorMod(int x, int y) 返回 |
static long |
floorMod(long x, long y) 返回 |
static int |
incrementExact(int a) 返回自變數1,如果結果溢位int,則 |
static long |
incrementExact(long a) 返回一個增加1的引數,如果結果溢位long,則 |
static int |
multiplyExact(int x, int y) 返回引數的乘積,如果結果溢位int,則丟擲 |
static long |
multiplyExact(long x, long y) 返回引數的乘積,如果結果溢位long,則丟擲 |
static int |
negateExact(int a) 返回引數的否定,如果結果溢位int,則 |
static long |
negateExact(long a) 返回引數的否定,如果結果溢位long,則 |
static long |
round(double a) 返回引數中最接近的 |
static int |
round(float a) 返回引數中最接近的 |
static int |
subtractExact(int x, int y) 返回引數的差異,如果結果溢位int,則丟擲 |
static long |
subtractExact(long x, long y) 返回引數的差異,如果結果溢位long,則丟擲 |
static int |
toIntExact(long value) 返回 |
java原始碼
public final class Math {
private Math() {}
public static int round(float a) {
int intBits = Float.floatToRawIntBits(a);
int biasedExp = (intBits & FloatConsts.EXP_BIT_MASK)
>> (FloatConsts.SIGNIFICAND_WIDTH - 1);
int shift = (FloatConsts.SIGNIFICAND_WIDTH - 2
+ FloatConsts.EXP_BIAS) - biasedExp;
if ((shift & -32) == 0) { // shift >= 0 && shift < 32
// a is a finite number such that pow(2,-32) <= ulp(a) < 1
int r = ((intBits & FloatConsts.SIGNIF_BIT_MASK)
| (FloatConsts.SIGNIF_BIT_MASK + 1));
if (intBits < 0) {
r = -r;
}
// In the comments below each Java expression evaluates to the value
// the corresponding mathematical expression:
// (r) evaluates to a / ulp(a)
// (r >> shift) evaluates to floor(a * 2)
// ((r >> shift) + 1) evaluates to floor((a + 1/2) * 2)
// (((r >> shift) + 1) >> 1) evaluates to floor(a + 1/2)
return ((r >> shift) + 1) >> 1;
} else {
// a is either
// - a finite number with abs(a) < exp(2,FloatConsts.SIGNIFICAND_WIDTH-32) < 1/2
// - a finite number with ulp(a) >= 1 and hence a is a mathematical integer
// - an infinity or NaN
return (int) a;
}
}
public static long round(double a) {
long longBits = Double.doubleToRawLongBits(a);
long biasedExp = (longBits & DoubleConsts.EXP_BIT_MASK)
>> (DoubleConsts.SIGNIFICAND_WIDTH - 1);
long shift = (DoubleConsts.SIGNIFICAND_WIDTH - 2
+ DoubleConsts.EXP_BIAS) - biasedExp;
if ((shift & -64) == 0) { // shift >= 0 && shift < 64
// a is a finite number such that pow(2,-64) <= ulp(a) < 1
long r = ((longBits & DoubleConsts.SIGNIF_BIT_MASK)
| (DoubleConsts.SIGNIF_BIT_MASK + 1));
if (longBits < 0) {
r = -r;
}
// In the comments below each Java expression evaluates to the value
// the corresponding mathematical expression:
// (r) evaluates to a / ulp(a)
// (r >> shift) evaluates to floor(a * 2)
// ((r >> shift) + 1) evaluates to floor((a + 1/2) * 2)
// (((r >> shift) + 1) >> 1) evaluates to floor(a + 1/2)
return ((r >> shift) + 1) >> 1;
} else {
// a is either
// - a finite number with abs(a) < exp(2,DoubleConsts.SIGNIFICAND_WIDTH-64) < 1/2
// - a finite number with ulp(a) >= 1 and hence a is a mathematical integer
// - an infinity or NaN
return (long) a;
}
}
public static int addExact(int x, int y) {
int r = x + y;
// HD 2-12 Overflow iff both arguments have the opposite sign of the result
if (((x ^ r) & (y ^ r)) < 0) {
throw new ArithmeticException("integer overflow");
}
return r;
}
public static long addExact(long x, long y) {
long r = x + y;
// HD 2-12 Overflow iff both arguments have the opposite sign of the result
if (((x ^ r) & (y ^ r)) < 0) {
throw new ArithmeticException("long overflow");
}
return r;
}
public static int subtractExact(int x, int y) {
int r = x - y;
// HD 2-12 Overflow iff the arguments have different signs and
// the sign of the result is different than the sign of x
if (((x ^ y) & (x ^ r)) < 0) {
throw new ArithmeticException("integer overflow");
}
return r;
}
public static long subtractExact(long x, long y) {
long r = x - y;
// HD 2-12 Overflow iff the arguments have different signs and
// the sign of the result is different than the sign of x
if (((x ^ y) & (x ^ r)) < 0) {
throw new ArithmeticException("long overflow");
}
return r;
}
public static int multiplyExact(int x, int y) {
long r = (long)x * (long)y;
if ((int)r != r) {
throw new ArithmeticException("integer overflow");
}
return (int)r;
}
public static long multiplyExact(long x, long y) {
long r = x * y;
long ax = Math.abs(x);
long ay = Math.abs(y);
if (((ax | ay) >>> 31 != 0)) {
// Some bits greater than 2^31 that might cause overflow
// Check the result using the divide operator
// and check for the special case of Long.MIN_VALUE * -1
if (((y != 0) && (r / y != x)) ||
(x == Long.MIN_VALUE && y == -1)) {
throw new ArithmeticException("long overflow");
}
}
return r;
}
public static int incrementExact(int a) {
if (a == Integer.MAX_VALUE) {
throw new ArithmeticException("integer overflow");
}
return a + 1;
}
public static long incrementExact(long a) {
if (a == Long.MAX_VALUE) {
throw new ArithmeticException("long overflow");
}
return a + 1L;
}
public static int decrementExact(int a) {
if (a == Integer.MIN_VALUE) {
throw new ArithmeticException("integer overflow");
}
return a - 1;
}
public static long decrementExact(long a) {
if (a == Long.MIN_VALUE) {
throw new ArithmeticException("long overflow");
}
return a - 1L;
}
public static int negateExact(int a) {
if (a == Integer.MIN_VALUE) {
throw new ArithmeticException("integer overflow");
}
return -a;
}
public static long negateExact(long a) {
if (a == Long.MIN_VALUE) {
throw new ArithmeticException("long overflow");
}
return -a;
}
public static int toIntExact(long value) {
if ((int)value != value) {
throw new ArithmeticException("integer overflow");
}
return (int)value;
}
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 static long floorDiv(long x, long y) {
long r = x / y;
// if the signs are different and modulo not zero, round down
if ((x ^ y) < 0 && (r * y != x)) {
r--;
}
return r;
}
public static int floorDiv(int x, int y) {
int r = x / y;
// if the signs are different and modulo not zero, round down
if ((x ^ y) < 0 && (r * y != x)) {
r--;
}
return r;
}
public static int floorMod(int x, int y) {
int r = x - floorDiv(x, y) * y;
return r;
}
public static long floorMod(long x, long y) {
return x - floorDiv(x, y) * y;
}
}
public final class StrictMath {
private StrictMath() {}
public static int round(float a) {
return Math.round(a);
}
public static long round(double a) {
return Math.round(a);
}
public static int addExact(int x, int y) {
return Math.addExact(x, y);
}
public static long addExact(long x, long y) {
return Math.addExact(x, y);
}
public static int subtractExact(int x, int y) {
return Math.subtractExact(x, y);
}
public static long subtractExact(long x, long y) {
return Math.subtractExact(x, y);
}
public static int multiplyExact(int x, int y) {
return Math.multiplyExact(x, y);
}
public static long multiplyExact(long x, long y) {
return Math.multiplyExact(x, y);
}
public static int toIntExact(long value) {
return Math.toIntExact(value);
}
public static int floorDiv(int x, int y) {
return Math.floorDiv(x, y);
}
public static long floorDiv(long x, long y) {
return Math.floorDiv(x, y);
}
public static int floorMod(int x, int y) {
return Math.floorMod(x , y);
}
public static long floorMod(long x, long y) {
return Math.floorMod(x, y);
}
public static int abs(int a) {
return Math.abs(a);
}
public static long abs(long a) {
return Math.abs(a);
}
public static float abs(float a) {
return Math.abs(a);
}
public static double abs(double a) {
return Math.abs(a);
}
}