Math类和StrictMath类源码详解

Math类和StrictMath类源码详解

类的定义

public final class Math {

}
public final class StrictMath {

}

被final修饰的类不能被继承,即它不能拥有自己的子类

Math类会提供一些三角函数

对比

   public static double sin(double a) {
        return StrictMath.sin(a); // default impl. delegates to StrictMath
    }
    public static native double sin(double a);

Java平台有个用户和本地C代码进行互操作的API,称为Java Native Interface (Java本地接口)。

使用native关键字说明这个方法是原生函数,也就是这个方法是用C/C++语言实现的,并且被编译成了DLL,由java去调用。
这些函数的实现体在DLL中,JDK的源代码中并不包含,你应该是看不到的。对于不同的平台它们也是不同的。这也是java的底层机制,实际上java就是在不同的平台上调用不同的native方法实现对操作系统的访问的。

 

两个类最本质的区别-strictfp

   public static strictfp double toRadians(double angdeg) {
        // Do not delegate to Math.toRadians(angdeg) because
        // this method has the strictfp modifier.
        return angdeg / 180.0 * PI;
    }
    public static double toRadians(double angdeg) {
        return angdeg / 180.0 * PI;
    }

strictfp解释:

 

关于floor和floorMod方法

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

 x = Math.getExponent(y)相当于y = Math.pow(2, x),2^x
double exponent = Math.getExponent(1);//无偏差指数
如果参数为NaN或无穷大,那么结果是Float.MAX_EXPONENT+1。
如果参数是零或小于正常值,那么结果是Float.MIN_EXPONENT-1。

 

关于0和0L

java的内存体制
example:
long fw = 10000000000L;
实际上内存中fw只是一个long类型的变量,它存在于向stack(栈)中,数值并不在其中存放,它指向heap(堆)中另一块真正存放数值的内存,加L的目的就是为了让heap中也创建一块long类型所需要的内存,用来来放数值。
所以说=前后两者其实是在不同的两块内存,只不过有个无形的指针将两者连接起来了。

不加的后果:

  1. 不加L默认是int,int转为long是安全的,所以会自动转,能编译通过
  2. 浮点数不加F默认是double类型,double转float可能损失精度,因为不会自动转,编译通不过
  3. 如果超过int的取值范围还不加L,那么也会直接报错了

 

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

  java中求模使用的是Math.floorMod(被除数, 除数)方法

 当被除数和除数同号的时候,求余和取模得到的结果是相等的

       求余得到商的过程是先用绝对值求商再添上正负号

       求模得到商的过程是用绝对值求商的值+1再添正负号,能整除的除外。

       求余过程中:

              余数的正负号取决于被除数,被除数为正则为正,被除数为负则为负

       求模过程中:

              模的正负号取决于除数,除数为正则为正,除数为负责为负

 

 

    public static int abs(int 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 int max(int a, int b) {
        return (a >= b) ? a : b;
    }
    public static float max(float a, float b) {
        if (a != a)
            return a;   // a is NaN
        if ((a == 0.0f) &&
            (b == 0.0f) &&
            (Float.floatToRawIntBits(a) == negativeZeroFloatBits)) {
            // Raw conversion ok since NaN can't map to -0.0.
            return b;
        }
        return (a >= b) ? a : b;
    }

 

 

 

 

 

 

 

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

wespten

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值