2015-12-18 28 views
1

我移植一些C++ samplesJava包装4个整数到一个单一的[10,10,10,2]整数

我现在坚持努力收拾四个整数到一个单一的一个在下面的布局[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] 

是有意义至今。现在我清理了左侧的值,我想把它们拖到正确的地方。但是当我这样做的时候,我得到了左边填充1的缺口,我猜是因为java(?)中有符号整数。

然后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] 

那么,为什么会出现这种情况,如何能解决这个问题?也许只用我感兴趣的位来进行“与”运算?

+0

这是无效的C.你用C++编译器编译C代码吗? – Lundin

+0

我正在使用VS2015社区C++编译器我猜 – elect

+0

因为这是C++而不是C,你应该编辑你的文章。 – Lundin

回答

0
struct 
    { 
     int x : 10; 
     int y : 10; 
     int z : 10; 
     int w : 2; 
    } data; 

此代码是完全不可移植的,也就是说,如果它甚至可以按预期在当前系统上。

你绝对没有办法告诉这个结构将包含什么。你不知道什么是MSB,你不知道如何处理签名,你不知道是否会出现填充,你不知道是否会出现填充等等。See this

唯一的便携式解决方案是使用原始uint32_t并将值移位到位。

+0

我不是那个代码的作者 – elect

相关问题