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

返回值为 double绝对值。

static float abs(float a)

返回 float值的绝对值。

static int abs(int a)

返回值为 int绝对值。

static long abs(long a)

返回值为 long绝对值。

static double ceil(double a)

返回大于或等于参数的最小(最接近负无穷大) double值,等于一个数学整数。

static double copySign(double magnitude, double sign)

使用第二个浮点参数的符号返回第一个浮点参数。

static float copySign(float magnitude, float sign)

使用第二个浮点参数的符号返回第一个浮点参数。

static double floor(double a)

返回小于或等于参数的最大(最接近正无穷大) double值,等于一个数学整数。

static int getExponent(double d)

返回a的表示中使用的无偏指数 double

static int getExponent(float f)

返回a的表示中使用的无偏指数 float

static double rint(double a)

返回与参数最接近值的 double值,并且等于数学整数。

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

猜你喜欢

转载自blog.csdn.net/qq_35029061/article/details/85781914
今日推荐