我正在将C++ samples移植到Java

我现在被困在尝试按以下布局[10、10、10、2]以位为单位将四个整数打包为一个整数,即第一个int将占据前10个位,与第二个和第三个整数相似,而最后一位只是最后两位。

在C++示例中,这是打包它们的代码:

GLM_FUNC_QUALIFIER uint32 packSnorm3x10_1x2(vec4 const & v)
    {
        detail::i10i10i10i2 Result;
        Result.data.x = int(round(clamp(v.x,-1.0f, 1.0f) * 511.f));
        Result.data.y = int(round(clamp(v.y,-1.0f, 1.0f) * 511.f));
        Result.data.z = int(round(clamp(v.z,-1.0f, 1.0f) * 511.f));
        Result.data.w = int(round(clamp(v.w,-1.0f, 1.0f) *   1.f));
        return Result.pack;
    }

Result.data是以下struct:
union i10i10i10i2
    {
        struct
        {
            int x : 10;
            int y : 10;
            int z : 10;
            int w : 2;
        } data;
        uint32 pack;
    };

使用等于[-1f,-1f,0f,1f]的输入,我们得到一个等于Result.data[-511,-511,0,1],并且此返回值1074267649在二进制中为:
        0                       -511
   |          |             |          |
 0100 0000 0000 1000 0000 0110 0000 0001
 ||             |          |
 1                  -511

到目前为止,我所做的是:
public static int packSnorm3x10_1x2(float[] v) {
    int[] tmp = new int[4];
    tmp[0] = (int) (Math.max(-1, Math.min(1, v[0])) * 511.f);
    tmp[1] = (int) (Math.max(-1, Math.min(1, v[1])) * 511.f);
    tmp[2] = (int) (Math.max(-1, Math.min(1, v[2])) * 511.f);
    tmp[3] = (int) (Math.max(-1, Math.min(1, v[3])) * 1.f);
    int[] left = new int[4];
    left[0] = (tmp[0] << 22);
    left[1] = (tmp[1] << 22);
    left[2] = (tmp[2] << 22);
    left[3] = (tmp[3] << 30);
    int[] right = new int[4];
    right[0] = (left[0] >> 22);
    right[1] = (left[1] >> 12);
    right[2] = (left[2] >> 2);
    right[3] = (left[3] >> 0);
    return right[0] | right[1] | right[2] | right[3];
}
tmp[-511,-511,0,1]left[-2143289344,-2143289344,0,1073741824],二进制格式是:
[1000 0000 0100 0000 0000 0000 0000 0000,
 1000 0000 0100 0000 0000 0000 0000 0000,
 0000 0000 0000 0000 0000 0000 0000 0000,
 0100 0000 0000 0000 0000 0000 0000 0000]

到目前为止,这是有道理的。现在,我清除了左边的值,我想将它们拖到右边的右边。但是,当我这样做时,我猜想是因为java(?)中带符号的int导致左边的空白填充为1。

然后right[-511,-523264,0,1073741824]或:
[1111 1111 1111 1111 1111 1110 0000 0001,
 1111 1111 1111 1000 0000 0100 0000 0000,
 0000 0000 0000 0000 0000 0000 0000 0000,
 0100 0000 0000 0000 0000 0000 0000 0000]

那么,为什么会发生这种情况,我该如何解决呢?也许只对我感兴趣的位进行ANDing操作?

最佳答案

无符号右移运算符>>>将零移位到最左边的位置。

资料来源:https://docs.oracle.com/javase/tutorial/java/nutsandbolts/op3.html

关于java - 将4个整数打包为一个[10,10,10,2]整数,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/34352434/

10-15 19:07