跳至主要內容

Math-Max&Min

cylin...大约 3 分钟

1. 数据类型

一、byte,占用一个字节,取值范围为 -128-127,默认是“\u0000”,表示空

二、short,占用两个字节,取值范围为 -32768-32767

三、int,占用四个字节,-2147483648-2147483647

四、long,占用八个字节,对 long 型变量赋值时必须加上"L"或“l”,否则不认为是 long 型

五、float,占用四个字节,对 float 型进行赋值的时候必须加上“F”或“f”,如果不加,会产生编译错误,因为系统自动将其定义为 double 型变量。double转换为float类型数据会损失精度。float a = 12.23产生编译错误的,float a = 12是正确的

六、double,占用八个字节,对 double 型变量赋值的时候最好加上“D”或“d”,但加不加不是硬性规定

七、char,占用两个字节,在定义字符型变量时,要用单引号括起来

八、boolean,只有两个值“true”和“false”,默认值为false,不能用0或非0来代替,这点和C语言不同

整数类型(byte/short/int/long)中,对于未声明数据类型的整形,其默认类型为int型。在浮点类型(float/double)中,对于未声明数据类型的浮点型,默认为double型

2. 源码

public final class Math {
 
    private Math() {}
 
    public static int max(int a, int b) {
        return (a >= b) ? a : b;
    }
 
    public static long max(long a, long b) {
        return (a >= b) ? a : b;
    }
    //在有保证的非NaN参数上使用原始的逐位转换。
    private static long negativeZeroFloatBits  = Float.floatToRawIntBits(-0.0f);
    private static long negativeZeroDoubleBits = Double.doubleToRawLongBits(-0.0d);
 
    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;
    }
 
    public static double max(double a, double b) {
        if (a != a)
            return a;   // a is NaN
        if ((a == 0.0d) &&
            (b == 0.0d) &&
            (Double.doubleToRawLongBits(a) == negativeZeroDoubleBits)) {
            // Raw conversion ok since NaN can't map to -0.0.
            return b;
        }
        return (a >= b) ? a : b;
    }
 
    public static int min(int a, int b) {
        return (a <= b) ? a : b;
    }
 
    public static long min(long a, long b) {
        return (a <= b) ? a : b;
    }
 
    public static float min(float a, float b) {
        if (a != a)
            return a;   // a is NaN
        if ((a == 0.0f) &&
            (b == 0.0f) &&
            (Float.floatToRawIntBits(b) == negativeZeroFloatBits)) {
            // Raw conversion ok since NaN can't map to -0.0.
            return b;
        }
        return (a <= b) ? a : b;
    }
 
    public static double min(double a, double b) {
        if (a != a)
            return a;   // a is NaN
        if ((a == 0.0d) &&
            (b == 0.0d) &&
            (Double.doubleToRawLongBits(b) == negativeZeroDoubleBits)) {
            // Raw conversion ok since NaN can't map to -0.0.
            return b;
        }
        return (a <= b) ? a : b;
    }	
 
}

3. 解读

private static long negativeZeroFloatBits  = Float.floatToRawIntBits(-0.0f);
  • 将其初始化为表示浮点数 -0.0f 的原始位表示形式。在 Java 中,浮点数的位表示可以通过 Float.floatToRawIntBits() 方法来获取
  • -0.0f 表示负零,它与正零在数值上相等,但在位表示上有所不同。在 IEEE 754 浮点数标准中,负零的符号位为 1,其余位都为 0。这种位模式可以通过 Float.floatToRawIntBits() 转换为整数形式,并存储在 negativeZeroFloatBits
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;
}
  • if (a != a) return a;: 这一行检查 a 是否为 NaN(非数字)。在 Java 中,NaN 与任何值都不相等,包括它自己。因此,如果 aNaN,则条件为真,代码将返回 a 本身
  • if ((a == 0.0f) && (b == 0.0f) && (Float.floatToRawIntBits(a) == negativeZeroFloatBits)) return b;: 这一行检查如果 ab 都为零,并且 a 是负零,那么返回 b。负零和正零在二进制表示中是不同的,但在数学上它们相等。这个检查确保在这种情况下,返回的是正零而不是负零