首页 > 编程语言 >Math类和StrictMath类源码详解

Math类和StrictMath类源码详解

时间:2023-02-23 23:10:00浏览次数:40  
标签:return int double 源码 static 0.0 public 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解释:

Math类和StrictMath类源码详解_java

Math类和StrictMath类源码详解_Math_02

 

关于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再添正负号,能整除的除外。

       求余过程中:

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

       求模过程中:

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

Math类和StrictMath类源码详解_Math_03

Math类和StrictMath类源码详解_Math_04

 

 

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

 

 

 

 

 

 

 

标签:return,int,double,源码,static,0.0,public,Math,StrictMath
From: https://blog.51cto.com/u_11837698/6081988

相关文章

  • java的数组与Arrays类源码详解
    java的数组与Arrays类源码详解java.util.Arrays类是JDK提供的一个工具类,用来处理数组的各种方法,而且每个方法基本上都是静态方法,能直接通过类名Arrays调用。类的定义......
  • java的StringBuilder与StringBuffer类源码详解
     java的StringBuilder与StringBuffer类源码详解类的定义abstractclassAbstractStringBuilderimplementsAppendable,CharSequence{char[]value;intcount;......
  • java枚举Enum与Enumeration源码详解
    java枚举Enum与Enumeration源码详解类的定义publicabstractclassEnum<EextendsEnum<E>>implementsComparable<E>,Serializable{}属性定义privatefinalStr......
  • java的Integer类源码详解
    java的Integer类源码详解类的定义publicfinalclassIntegerextendsNumberimplementsComparable<Integer>{@NativepublicstaticfinalintMIN_VALUE=0x800......
  • java日期类Date与DateFormat源码详解
    java日期类Date与DateFormat源码详解Date类的定义publicclassDateimplementsjava.io.Serializable,Cloneable,Comparable<Date>{privatestaticfinalBaseCal......
  • java的DateFormat、SimpleDateFormate类源码的详解
    java的DateFormat、SimpleDateFormate类源码的详解抽象类Format的定义publicabstractclassFormatimplementsSerializable,Cloneable{privatestaticfinallong......
  • java的NumberFormat、DecimalFormat、MessageFormat类源码详解
    java的NumberFormat、DecimalFormat、MessageFormat类源码详解NumberFormat类的定义publicabstractclassNumberFormatextendsFormat{protectedNumberFormat(){......
  • 深入学习jquery源码之each()
    $.each()遍历一个数组或对象,可以是DOM、json等格式,等价于for循环返回值:jQuery.each(callback) 参数:对于每个匹配的元素所要执行的函数概述:以每一个匹配的元素作为上下文......
  • 深入学习jquery源码之trigger()与triggerHandler()
    深入学习jquery源码之trigger()与triggerHandler()trigger(type,[data])概述:在每一个匹配的元素上触发某类事件。这个函数也会导致浏览器同名的默认行为的执行。比如,如果用......
  • 深入学习jquery源码之map()
    概述将一组元素转换成其他数组(不论是否是元素数组)你可以用这个函数来建立一个列表,不论是值、属性还是CSS样式,或者其他特别形式。这都可以用'$.map()'来方便的建立。参数call......