【问题标题】:Reading 10-bit fixed-point float读取 10 位定点浮点数
【发布时间】:2014-09-17 18:19:58
【问题描述】:

我有一个包含 10 位定点值的二进制文件,我需要将其转换为 Java float。我几乎可以肯定“格式”是x.xxxxxxxxx,其中 x 有点。而且我确实认为我了解手工操作this 的基础知识。

我必须对位做:x + 0.5*x + 0,25*x... 等。例如

1010110010 = 1×1 + 0×½ + 1×¼ + 0×⅛ + 1×¹⁄₁₆ + 1×¹⁄₃₂...

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

文件是小尾数。

【问题讨论】:

  • 不!位,而不是字节或类似的东西:) 我的“格式”中的“x”代表位,0/1
  • 好的,我撤回了接近投票,但您可能想编辑您的问题,因为它读起来好像您的意思是 x.xxxxxxxxx 作为 ASCII 表示。例如,您可以以十六进制转储的形式发布一个示例,以及您希望它解码为什么值。
  • 你应该给我们更多的上下文,尤其是这是什么文件。
  • 如果你有10位,并且“二进制点在第一位和第二位之间,这只是意味着该数字除以2到第9位,即512。所以把值放在低位int 的结尾,转换为浮点数,除以 512,得到你的数字。

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


【解决方案1】:

如果你有 10 位,并且“二进制点”在第一位和第二位之间,这只是意味着该数字除以 2 到第 9 位,即 512。所以将值放在 int 的低端, 转换为浮点数,除以 512,得到你的数字。

float finalAnswer = bitsInLowOrderEndOfInt / 512.0;

【讨论】:

  • 您应该将问题 cmets 中的解释添加到您的答案中。你是对的,但你写的东西是无法接近的。
  • 很抱歉提出问题。 bitsInLowOrderEndOfInt 代表什么?这意味着我应该将 10 位读取为无符号整数? 0-1023?
  • 需要将这10位读取为二进制值,取值范围为0-1023
【解决方案2】:

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

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;
}

【讨论】:

    【解决方案3】:

    我必须对位做:x,0.5*x+0.25*x.... 等等。

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

    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;
    }
    

    【讨论】:

    • (1.0 / i) 来自哪里?
    • 其实是OP写的,但一定是(1.0 / 2*i),我去编辑
    • 从二进制文件转换为布尔列表已经非常昂贵了。没有人像那样单独存储位。但更糟糕的是Math.pow(2, -1*i),它要慢得多
    【解决方案4】:

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

    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 位有 210 个数字,因此 0 .. 1023。 这表明固定点基于 1000 左右,可能是 9.99

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

    附注没有测试移位,顺便说一下,它也可能是小端。

    【讨论】:

    • 文件实际上是小端。我知道这是事实,但在实践中我并不完全理解。
    • 你确定是定点的吗?它看起来更像 BCD,将 3 位数字打包成 10 位,并将无关值用于其他目的:1023 = 小数点,1022 = 负数左右。 (事后看来,我对精确拟合 10 位的倍数的检查是愚蠢的。)
    • 我实际上是在对 Dungeon Keeper 2 网格和动画进行逆向工程 (github.com/tonihele/OpenDungeonKeeper)。我有一个社区创建的文档,说明这些是 3D 坐标。 Z、Y、X,每一个都以 10 位表示。并用浮点数缩放。在这种情况下,浮点数是 0.82xxx 并且缩放的矢量坐标应该很小,小于 1。到目前为止,文档已经到位。我得出的结论是,我只是不明白向量分量的形成。我只有反复试验来验证这一点。
    • github.com/tonihele/OpenDungeonKeeper/blob/master/src/toniarts/… - 这就是魔法,就在第 398 行附近。如果这对您有任何帮助或兴趣。
    • 所以:double coord = (0.82 * rawInt) / 1024;(双除法)。最多为 0.82;也许根本没有除法,0.82 * 1024 ≈ 840。祝你好运,我正在冒险工作的地牢。
    【解决方案5】:

    或者只是直接从原始位构造浮点数

    假设二进制值被读入v的低10位

    if (v == 0)
       return 0.0f;
    
    // shift the mantissa to the correct position and drop the implicit 1 bit
    int mantissa = (v << (23 - Integer.highestOneBit(v))) & 0x7ffff;
    int exponent = (-9 + 127) << 23;
    
    return Float.intBitsToFloat(mantissa | exponent);
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-06-13
      • 1970-01-01
      • 2019-10-08
      • 2014-04-01
      • 2023-03-13
      • 2013-09-12
      • 1970-01-01
      相关资源
      最近更新 更多