在JAVA中读取10位定点浮点数

时间:2014-09-17 18:19:58

标签: java parsing bit-manipulation bits fixed-point

我有一个二进制文件,它还有10位定点值,我需要转换为JAVA float。我几乎可以肯定"格式"是x.xxxxxxxxx,其中x是一个位。我确实认为我理解手工执行此操作的基础知识(http://www.toves.org/books/float/)。

我必须做的事情: x,0.5 * x + 0,25 * x ....等等。

1010110010将= 1 * 1。 0 *(1/2)+ 1 *(1/4)+ 0 *(1/8)+ 1 *(1/16)+ 1 *(1/32)....

但我不知道如何在JAVA中这样做。我一次只能读取一个BYTE文件,一个值读取2个字节= 16位。

该文件位于LITTLE ENDIAN。

5 个答案:

答案 0 :(得分:2)

如果你有10位,那么"二进制点"在第一位和第二位之间,这意味着数字除以2到9或512.所以将值放在int的低端,转换为浮点数,除以512,然后你得到你的数字。

float finalAnswer = bitsInLowOrderEndOfInt / 512.0;

答案 1 :(得分:1)

不是计算每个位,而是计算指数更有效。

public double parse (InputStream is) {
    long value = 0, factor = 0;
    for(;;) {
        int ch = is.read();
        if (ch == '.') {
            factor = 1;
        } else if(ch == '0' || ch = '1') {
            factor *= 2;
            value = value * 2 + ch - '0';
        } else {
            break;
        }
    }
    return factor == 0 ? value : (double) value / factor;
}

答案 2 :(得分:0)

  

我必须对这些位进行处理:x,0.5 * x + 0.25 * x ....等等。

这在Java中实际上并不困难。假设您将这些位转换为boolean s,您的代码可能如下所示:

public double parse (boolean ... bits)
{
    double val = (bits[0] ? 1 : 0); // note to check that bits[0] exists
    for (int i = 1; i < bits.length; i++)
        val += (1.0 / 2*i) * (bits[i] ? 1 : 0) * Math.pow(2, -1*i);
    return val;
}

答案 3 :(得分:0)

从字节到10位原始int的转换可能是这样的:

Path file = Paths.get("....");
byte[] data = Files.readAllBytes(file);

// data is a sequence of 10 bit fixed-point floats
if (data.length % 5 != 0) {
    throw new IllegalArgumentException(
        "File length is not a multiple of 10 bits: " + file);
}
int bitCount = data.length * 8;
bitCount = bitCount - (bitCount % 10); // When without check.
int[] rawInts = new int[bitCount / 10];
for (int bitIx = 0; bitIx < bitCount; bitIx += 10) {
    int byteIx0 = bitIx / 8;
    int byte0 = data[byteIx0) & 0xFF;
    int byteIx1 = byteIx0 + 1;
    int byte1 = data[byteIx1) & 0xFF;
    int off = bitIx % 8;

    int rawInt = ((byte0 << off + 2) & 0x3FF)
        | (byte1 >> (8 - (2 + off));
    rawInts[bitIx / 10] = rawInt;
}

现在为定点格式:10位一个有2个 10 数,因此0 ... 1023。 这表明固定点基于1000,可能是9.99

int integralPart = rawInt / 100;
int decimals = rawInt % 100;

P.S。没有测试位移,顺便说一句也可能是小端。

答案 4 :(得分:0)

另一种方法是直接从原始位转换

假设二进制值被读入v

的低10位
if (v == 0)
   return 0.0f;

int mantissa = (v << (23 - Integer.highestOneBit(v))) & 0x7ffff; // shift the correct position and drop the implicit 1 bit
int exponent = (-9 + 127) << 23;

return Float.intBitsToFloat(mantissa | exponent);