1. 程式人生 > >深入學習java原始碼之Math.addExact()與 Math.multiplyExact()

深入學習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)

返回值為 double絕對值。

static float abs(float a)

返回 float值的絕對值。

static int abs(int a)

返回值為 int絕對值。

static long abs(long a)

返回值為 long

絕對值。

static int addExact(int x, int y)

返回其引數的總和,如果結果溢位int,則丟擲 int

static long addExact(long x, long y)

返回其引數的總和,如果結果溢位long,則丟擲 long

static int decrementExact(int a)

返回一個遞減1的引數,如果結果溢位int,則 int

static long decrementExact(long a)

將返回的引數遞減1,如果結果溢位long,則 long

static double floor(double a)

返回小於或等於引數的最大(最接近正無窮大) double值,等於一個數學整數。

static int floorDiv(int x, int y)

返回小於或等於代數商的最大(最接近正無窮大) int值。

static long floorDiv(long x, long y)

返回小於或等於代數商的最大(最接近正無窮大) long值。

static int floorMod(int x, int y)

返回 int引數的底部模數。

static long floorMod(long x, long y)

返回 long引數的底模數。

static int incrementExact(int a)

返回自變數1,如果結果溢位int,則 int

static long incrementExact(long a)

返回一個增加1的引數,如果結果溢位long,則 long

static int multiplyExact(int x, int y)

返回引數的乘積,如果結果溢位int,則丟擲 int

static long multiplyExact(long x, long y)

返回引數的乘積,如果結果溢位long,則丟擲 long

static int negateExact(int a)

返回引數的否定,如果結果溢位int,則 int

static long negateExact(long a)

返回引數的否定,如果結果溢位long,則 long

static long round(double a)

返回引數中最接近的 long ,其中 long四捨五入為正無窮大。

static int round(float a)

返回引數中最接近的 int ,其中 int四捨五入為正無窮大。

static int subtractExact(int x, int y)

返回引數的差異,如果結果溢位int,則丟擲 int

static long subtractExact(long x, long y)

返回引數的差異,如果結果溢位long,則丟擲 long

static int toIntExact(long value)

返回long引數的值; 如果值溢位int,則int

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);
    }
	
}