源码分析,基本上都加载注解上了,如有谬误,请指正,谢谢。
jdk1.8.0_161
/**
* auther: jiyx
* date: 2018/9/20.
* float在计算机中占32字节,存储内容如下:
* 1.符号位(1bit),0表示正数。1表示负数
* 2.指数位(8bit),无符号数,范围0~255,但是指数位可能为负,所以这里有一个基数127.存储的时候需要真实指数+127
* 3.尾数位(23位),有效数字。
* 如8.25,二进制是1000.01,
* 小数位求二进制方法(乘2取整法,即每一步将十进制小数部分乘以2,所得积的小数点左边的数字(0或1)作为二进制表示法中的数字,直到满足你的精确度为止)
* 那么转换成指数形式就是1.00001 * 2^3
* 那么指数位就是3 + 127,二进制表示法10000010
* 符号位就是0,
* 尾数位就是00001,这里可以直接省略小数点前的1,因为这里一直都是1,所以不需要
* 那么最后8.25就是0100 0001 0000 0100 0000 0000 0000 0000
*/
public class Float extends Number implements Serializable {
/**
* 正无穷,相当于Float.intBitsToFloat(0x7f800000)
*/
public static final float POSITIVE_INFINITY = 1.0f / 0.0f;
/**
* 负无穷,相当于Float.intBitsToFloat(0xff800000)
*/
public static final float NEGATIVE_INFINITY = -1.0f / 0.0f;
/**
* 非数字,相当于Float.intBitsToFloat(0x7fc00000)
*/
public static final float NaN = 0.0f / 0.0f;
/**
* float的最大有限制,值为 (2减去2的负23次方)乘以2的127次方
* 相当于Float.intBitsToFloat(0x7f7fffff)和十六进制的浮点字面值0x1.fffffeP+127f
*/
public static final float MAX_VALUE = 0x1.fffffeP+127f; // 3.4028235e+38f
/**
* float的最小的正正常值,2的负126次方,相当于16进制字面量0x1.0p-126f和Float.intBitsToFloat(0x00800000)
*/
public static final float MIN_NORMAL = 0x1.0p-126f; // 1.17549435E-38f
/**
* 最小的正数非零值,相当于16进制浮点字面量0x0.000002P-126f和Float.intBitsToFloat(0x1)
*/
public static final float MIN_VALUE = 0x0.000002P-126f; // 1.4e-45f
/**
* 有限浮点变量可能具有的最大指数,相当于Math.getExponent(Float.MAX_VALUE)
*/
public static final int MAX_EXPONENT = 127;
/**
* 标准化浮点变量的最小指数可能有,相当于Math.getExponent(Float.MIN_NORMAL)
*/
public static final int MIN_EXPONENT = -126;
/**
* float所占的bit数
*/
public static final int SIZE = 32;
/**
* float所占的byte数
*/
public static final int BYTES = SIZE / Byte.SIZE;
/**
* float的Class对象
*/
@SuppressWarnings("unchecked")
public static final Class<Float> TYPE = (Class<Float>) Class.getPrimitiveClass("float");
/**
* 返回float的字符串形式,
* 1.如果是非字符串则返回NaN。
* 2.还可能出现infinity(正无穷)和-infinity(负无穷)
* 3.当输入的是0的时候,如果是正数返回0.0,负数返回-0.0
* 4.当输入的数大于10的负3次方,小于10的7次方,返回的是十进制的整数位和小数位,小数位最后的多个零会合并成一个
* 5.当输入的数小于10的负3次方,大于10的7次方,返回的是科学计数法表示的数, 如Integer.MAX_VALUE返回2.14748365E9
*/
public static String toString(float f) {
return FloatingDecimal.toJavaFormatString(f);
}
/**
* 返回当前float的16进制形式
* 1.输入的非数字,返回非数字
* 2.还可能出现infinity(正无穷)和-infinity(负无穷)
* 3.零返回0x0.0p0和-0x0.0p0
* 4.标准的float将会返回类似0x1.097092p25,这种也是类似的科学计数法,
* 小数点之前的不变,p后边的数代表的指数位,这里的25即2的25次方。
* 5.如果数据低于正常float,即(FloatConsts.MIN_NORMAL),那么会返回0x0.开头的计数法
* 如0x0.000002p-126
*<table border>
* <caption>Examples</caption>
* <tr><th>Floating-point Value</th><th>Hexadecimal String</th>
* <tr><td>{@code 1.0}</td> <td>{@code 0x1.0p0}</td>
* <tr><td>{@code -1.0}</td> <td>{@code -0x1.0p0}</td>
* <tr><td>{@code 2.0}</td> <td>{@code 0x1.0p1}</td>
* <tr><td>{@code 3.0}</td> <td>{@code 0x1.8p1}</td>
* <tr><td>{@code 0.5}</td> <td>{@code 0x1.0p-1}</td>
* <tr><td>{@code 0.25}</td> <td>{@code 0x1.0p-2}</td>
* <tr><td>{@code Float.MAX_VALUE}</td>
* <td>{@code 0x1.fffffep127}</td>
* <tr><td>{@code Minimum Normal Value}</td>
* <td>{@code 0x1.0p-126}</td>
* <tr><td>{@code Maximum Subnormal Value}</td>
* <td>{@code 0x0.fffffep-126}</td>
* <tr><td>{@code Float.MIN_VALUE}</td>
* <td>{@code 0x0.000002p-126}</td>
* </table>
*/
public static String toHexString(float f) {
// 低于正常float
if (Math.abs(f) < FloatConsts.MIN_NORMAL
&& f != 0.0f) {
// 首先调整当前的指数到double的指数精度,然后将返回的结果再替换回float的指数精度
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返回的和Float一样,而且float在double范围内,所以直接使用Double
return Double.toHexString(f);
}
}
/**
* 根据字符串返回Float对像
* 1.入参不能是null,如果是抛出NullPointerException
* 2.入参中前后的空格会使用trim消掉
*/
public static Float valueOf(String s) throws NumberFormatException {
return new Float(parseFloat(s));
}
/**
* Float的自动装箱
*/
public static Float valueOf(float f) {
return new Float(f);
}
/**
* 将指定的字符串解析为float
*/
public static float parseFloat(String s) throws NumberFormatException {
return FloatingDecimal.parseFloat(s);
}
/**
* 判断指定数是否是非数字
*/
public static boolean isNaN(float v) {
return (v != v);
}
/**
* 判断指定数是否是无穷数,不区分正负无穷
*/
public static boolean isInfinite(float v) {
return (v == POSITIVE_INFINITY) || (v == NEGATIVE_INFINITY);
}
/**
* 判断指定float是否在Float有效范围之内
*/
public static boolean isFinite(float f) {
return Math.abs(f) <= FloatConsts.MAX_VALUE;
}
/**
* Float对象存储的float值
*/
private final float value;
/**
* 构造函数
*/
public Float(float value) {
this.value = value;
}
/**
* 构造函数
*/
public Float(double value) {
this.value = (float)value;
}
/**
* 构造函数
*/
public Float(String s) throws NumberFormatException {
value = parseFloat(s);
}
/**
* 判断当前存储的float是否是非数字
*/
public boolean isNaN() {
return isNaN(value);
}
/**
* 判断当前存储的float是否是无穷数
*/
public boolean isInfinite() {
return isInfinite(value);
}
/**
* toString
*/
public String toString() {
return Float.toString(value);
}
/**
* 缩窄到byte
*/
public byte byteValue() {
return (byte)value;
}
/**
* 缩窄到short
*/
public short shortValue() {
return (short)value;
}
/**
* 缩窄到int
*/
public int intValue() {
return (int)value;
}
/**
* 缩窄到long
*/
public long longValue() {
return (long)value;
}
/**
* 返回本身的float
*/
public float floatValue() {
return value;
}
/**
* 向上转型double
*/
public double doubleValue() {
return (double)value;
}
/**
* hashcode
*/
@Override
public int hashCode() {
return Float.hashCode(value);
}
/**
* hashcode
*/
public static int hashCode(float value) {
return floatToIntBits(value);
}
/**
* equals
*/
public boolean equals(Object obj) {
return (obj instanceof Float)
&& (floatToIntBits(((Float)obj).value) == floatToIntBits(value));
}
/**
* 返回float的bit形式的十进制形式,这里的二进制形式与int等数据不同。
* 参考开头对float二进制存储结构的介绍,也可以参考文末参考文章2、3
*
* 正无穷0x7f800000,负无穷0xff800000,NaN返回0x7fc00000
*
* 这个方法其实就2步,首先将float转换为bit表示形式,然后以int的方式读取bit的表示,而不是以float形式读取
*/
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;
}
/**
* 同方法floatToIntBits一样,唯一的区别是,传入的数是NaN时,
* 如果是floatToIntBits,返回的数是一样的,但是floatToRawIntBits,返回的是不同的
* 可以通过Float.NaN 和 Math.sqrt(-1)来进行测试
*/
public static native int floatToRawIntBits(float value);
/**
* 将float的bit形式所表示的十进制,转换成float的值。
* 输入0x7f800000,输出Infinity
* 输入0xff800000,输出-Infinity
* 输入内容在输入0x7f800001和0x7fffffff之间 返回NaN
* 输入内容在输入0xff800001和0xffffffff之间 返回NaN
*/
public static native float intBitsToFloat(int bits);
/**
* 比较大小
*/
public int compareTo(Float anotherFloat) {
return Float.compare(value, anotherFloat.value);
}
/**
* 静态比较
* 0.0和-0.0是不相等的
* NaN和-NaN是相等的
* NaN和NaN是相等的
* 但是要注意,Float.NaN == Float.NaN返回的是flase。
* 可以参考isNaN方法。具体原理可以参考文末的参考6
* 一般数与NaN不相等
*/
public static int compare(float f1, float f2) {
// 如果两个数都不为NaN时,直接进行比较
if (f1 < f2)
return -1;
if (f1 > f2)
return 1;
// 不能是用floatToRawIntBits方法,因为可能出现NaNs
int thisBits = Float.floatToIntBits(f1);
int anotherBits = Float.floatToIntBits(f2);
return (thisBits == anotherBits ? 0 : // Values are equal
(thisBits < anotherBits ? -1 : // (-0.0, 0.0) or (!NaN, NaN)
1)); // (0.0, -0.0) or (NaN, !NaN)
}
/**
* 求和
*/
public static float sum(float a, float b) {
return a + b;
}
/**
* 取大值
*/
public static float max(float a, float b) {
return Math.max(a, b);
}
/**
* 取小值
*/
public static float min(float a, float b) {
return Math.min(a, b);
}
/** use serialVersionUID from JDK 1.0.2 for interoperability */
private static final long serialVersionUID = -2671257302660747028L;
}
参考:
1.浮点数转二进制小数位转换规则
2.浮点数的二进制表示
3.float浮点数的二进制存储方式及转换
4.Java的NaN
5.wiki介绍NaN
6.Float.NaN的compare和==返回不一致问题
网友评论