1️⃣类定义
public final class Float extends Number implements Comparable<Float>
- 声明为final,不能被继承;
- 继承Number,可以进行Number类型之间的转换;
- 实现了Comparable,可以进行比较;
2️⃣属性
/**
* 正无穷 : 程序运行值为 Infinity(无穷)
*/
public static final float POSITIVE_INFINITY = 1.0f / 0.0f;
/**
* 负无穷 : 程序运行值为 -Infinity(负无穷)
*/
public static final float NEGATIVE_INFINITY = -1.0f / 0.0f;
/**
* 非数字的float变量运行值为 NaN
*/
public static final float NaN = 0.0f / 0.0f;
/**
* 最大值 : 3.4028235e+38f
*/
public static final float MAX_VALUE = 0x1.fffffeP+127f;
/**
* 最小值 : 1.17549435E-38f
*/
public static final float MIN_NORMAL = 0x1.0p-126f;
/**
* 最小正数值
*/
public static final float MIN_VALUE = 0x0.000002P-126f; // 1.4e-45f
/**
* 指数的最大值
*/
public static final int MAX_EXPONENT = 127;
/**
* 指数的最小值
*/
public static final int MIN_EXPONENT = -126;
/**
* 所占的位数(32位)
*/
public static final int SIZE = 32;
/**
* 字节数4个字节 ,这里除的是Byte的静态变量Byte.SIZE大小是8
*/
public static final int BYTES = SIZE / Byte.SIZE;
/**
* @SuppressWarnings("unchecked")表示对警告保持静默
* 获取Float的原始class对象
*/
@SuppressWarnings("unchecked")
public static final Class<Float> TYPE = (Class<Float>) Class.getPrimitiveClass("float");
/**
* float对象中具体的float值,定义为final
*/
private final float value;
/**
* 序列化
*/
private static final long serialVersionUID = -2671257302660747028L;
3️⃣构造器
/**
* 直接把float赋值给value属性
*/
public Float(float value) {
this.value = value;
}
/**
* 将double赋值给value属性并进行类型强转
*/
public Float(double value) {
this.value = (float)value;
}
/**
* 将string转化为float,底层调用FloatingDecimal类的parseFloat()方法
* 来解析单精度浮点小数,在parseFloat()方法内进行一通解析操作(与double
* 的底层解析一样,调用的都是readJavaFormatString()方法;
*/
public Float(String s) throws NumberFormatException {
value = parseFloat(s);
}
4️⃣方法
① toString()
/**
* 底层调用FloatingDecimal.toJavaFormatString(d)方法进行解析
*/
public static String toString(float f) {
return FloatingDecimal.toJavaFormatString(f);
}
/**
* 底层调用的是该类静态的toString()方法
*/
public String toString() {
return Float.toString(value);
}
② toHexString()
/**
* 将float转为16进制的字符串
*/
public static String toHexString(float f) {
/**
* 如果float的绝对值小于最小的正常值(public static final float MIN_NORMAL = 1.17549435E-38F;)
* 且float不等于0.0
*/
if (Math.abs(f) < FloatConsts.MIN_NORMAL
&& f != 0.0f ) {
// 调整指数以创建低于正常值的双精度数
// 用低于正常值的浮点数替换低于正常值的双指数
String s = Double.toHexString(Math.scalb((double)f,
/* -1022+126 */
DoubleConsts.MIN_EXPONENT-
FloatConsts.MIN_EXPONENT));
return s.replaceFirst("p-1022$", "p-126");
}
else // 如果不满足上述的判断条件则直接调用double的对应方法进行转换
return Double.toHexString(f);
}
③ valueOf()
/**
* 获取float对象,接收String类型入参然后调用本类parseFloat()方法进行转换
*/
public static Float valueOf(String s) throws NumberFormatException {
return new Float(parseFloat(s));
}
/**
* 获取float对象
*/
public static Float valueOf(float f) {
return new Float(f);
}
④ parseFloat()
/**
* 将字符串转换为float类型,底层调用FloatingDecimal.parseFloat(s),
* public Float(String s)构造器就是调用此方法进行操作的
*/
public static float parseFloat(String s) throws NumberFormatException {
return FloatingDecimal.parseFloat(s);
}
⑤ isNaN()
/**
* 判断一个float值是否是NAN(NAN的值不等于NAN的:
* 所有的无穷值都不相等,所以值和值本身比较若不相等则是true,
* 这里的不等指的是值的不等)
*/
public static boolean isNaN(float v) {
return (v != v);
}
/**
* 判断一个float值是否是NAN,调用静态isNaN()方法进行操作;
*/
public boolean isNaN() {
return isNaN(value);
}
⑥ isInfinite()
/**
* 有限判断,只与正无穷或负无穷进行比较,满足其中一个条件即为有限
*/
public static boolean isInfinite(float v) {
return (v == POSITIVE_INFINITY) || (v == NEGATIVE_INFINITY);
}
/**
* 有限判断,调用静态isInfinite()方法
*/
public boolean isInfinite() {
return isInfinite(value);
}
⑦ isFinite()
/**
* 判断是否超出范围
* 最大值为public static final float MAX_VALUE = 3.4028235E38F;
*/
public static boolean isFinite(float f) {
return Math.abs(f) <= FloatConsts.MAX_VALUE;
}
⑧ 来自于Number继承类的方法实现
/**
* 将当前对象强转为byte,继承自Number方法
*/
public byte byteValue() {
return (byte)value;
}
/**
* 将当前对象强转为short,继承自Number方法
*/
public short shortValue() {
return (short)value;
}
/**
* 将当前对象强转为int,继承自Number方法
*/
public int intValue() {
return (int)value;
}
/**
* 将当前对象强转为long,继承自Number方法
*/
public long longValue() {
return (long)value;
}
/**
* 获取float对象的float值,继承自Number方法
*/
public float floatValue() {
return value;
}
/**
* 将当前对象强转为double,继承自Number方法
*/
public double doubleValue() {
return (double)value;
}
⑨ hashCode() 与 equals()
/**
* hashCode调用静态的hashCode方法
*/
@Override
public int hashCode() {
return Float.hashCode(value);
}
/**
* hashCode底层调用floatToIntBits()方法进行处理
*/
public static int hashCode(float value) {
return floatToIntBits(value);
}
_______________________________________
/**
* 判断是不是同一类型且两个对象的值是否一致
*/
public boolean equals(Object obj) {
return (obj instanceof Float)
&& (floatToIntBits(((Float)obj).value) == floatToIntBits(value));
}
⑩ 其他方法
/**
* 该方法主要先通过调用floatToRawIntBits获取到IEEE 754标准对应的整型
* 数,然后再分别用FloatConsts.EXP_BIT_MASK和FloatConsts.SIGNIF_BIT_MASK
* 两个掩码去判断是否为NaN,0x7fc00000对应的即为NaN.
*/
public static int floatToIntBits(float value) {
int result = floatToRawIntBits(value);
// Check for NaN based on values of bit fields, maximum
// exponent and nonzero significand.
if ( ((result & FloatConsts.EXP_BIT_MASK) ==
FloatConsts.EXP_BIT_MASK) &&
(result & FloatConsts.SIGNIF_BIT_MASK) != 0)
result = 0x7fc00000;
return result;
}
____________________________________________________
/**
* floatToRawIntBits是一个本地方法,该方法主要是将一个
* 浮点数转成IEEE 754标准的二进制形式对应的整型数
*/
public static native int floatToRawIntBits(float value);
____________________________________________________
/**
* 将长bit换算成float值, native
*/
public static native float intBitsToFloat(int bits);
____________________________________________________
/**
* 比较两个float的值进行比较,调用静态的compare()方法
*/
public int compareTo(Float anotherFloat) {
return Float.compare(value, anotherFloat.value);
}
/**
* 比较float值的核心逻辑
*/
public static int compare(float f1, float f2) {
// 先根据实际的float值进行判断
if (f1 < f2)
return -1;
if (f1 > f2)
return 1;
// 因为可能有NaNs,所以不能直接比较thisBits与anotherBits的差值。
// 调用floatToIntBits获取两个float对象的IEEE 754码然后进行比较
int thisBits = Float.floatToIntBits(f1);
int anotherBits = Float.floatToIntBits(f2);
// 通过IEEE 754码进行比较,返回值逻辑与float实际值比较相同
return (thisBits == anotherBits ? 0 : (thisBits < anotherBits ? -1 : 1));
}
___________________________________________________
/**
* 求和操作
*/
public static float sum(float a, float b) {
return a + b;
}
/**
* 获取两个float值中的最大值,调用Math.max获取
*/
public static float max(float a, float b) {
return Math.max(a, b);
}
/**
* 获取两个float值中的最小值,调用Math.max获取
*/
public static float min(float a, float b) {
return Math.min(a, b);
}
5️⃣总结
- 方法中大量使用了重载
- 多数方法都是用到了IEEE 754码
- 大部分逻辑与double类一致,在学习这两个类源码的时候可以对比着进行学习;
网友评论