在Java中计算浮点数的整数对数基数2

时间:2015-05-21 07:49:00

标签: java

如何为Java中的浮点数找到日志库2,向下舍入(作为整数)?

有快速的方法吗?

1 个答案:

答案 0 :(得分:5)

您可以使用Java的标准数学库计算,使用对数基本规则的更改:

public static final int log2(float f)
{
    return (int)Math.floor(Math.log(f)/Math.log(2.0));
}

或者您可以利用这一信息明确存储在IEEE 754浮点数中的事实:

Taken from en.wikipedia.org/wiki/File:Float_example.svg

指数实际上恰好包含了您正在寻找的答案,您所要做的就是将其一直向右移位并从中减去127。当然,一些浮点值的指数为-127(表示为零)。这些被称为次正规值,并且提取它们的对数有点棘手。在这里使用查找表找到它:

private static final int[] logTable = new int[256];

static
{
    logTable[0] = logTable[1] = 0;
    for (int i=2; i<256; i++) logTable[i] = 1 + logTable[i/2];
    logTable[0] = -1;
}

public static final int log2(float f)
{
    int x = Float.floatToIntBits(f);
    int c = x >> 23;

    if (c != 0) return c - 127; //Compute directly from exponent.
    else //Subnormal, must compute from mantissa.
    {
        int t = x >> 16;
        if (t != 0) return logTable[t] - 133;
        else return (x >> 8 != 0) ? logTable[t] - 141 : logTable[x] - 149;
    }
}

此解决方案改编自here,比前一个解决方案快得多。除非你在复杂的空间中工作,否则这两种方法对于负值或无限值,零和NaN都会有未定义的结果 - 除非你在复杂空间中工作。