深入学习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);
}
}