Pack/Unpack 4个字节转化为整数
Pack/Unpack 4 bytes into Integer
正如标题所说,我一直在尝试使用 BitShifting 在 c# 中将 4 个完整的 0-255 字节打包成 1 个整数。我正在尝试压缩一些数据,目前使用 40 字节的数据。但实际上理论上我只需要 12 个字节,但为此我需要将所有数据压缩为 3 个整数。
目前我的数据是:
float3 pos; // Position Relative to Object
float4 color; // RGB is Compressed into X, Y is MatID, Z and W are unused
float3 normal; // A simple Normal -1 to 1 range
但理论上我可以压缩到:
int pos; // X, Y, Z, MatID - These are never > 200 nor negative
int color; // R, G, B, Unused Fourth Byte
int normal; // X, Y, Z, [0, 255] = [-1, 1] with 128 being 0, Unused Fourth Byte Should be plenty accurate for my needs
所以我的问题是我该怎么做?我对 Bit Shifting 相当陌生,还没有设法完成很多工作。
如果我没理解错的话,你需要在 4 个字节中存储 4 个值(每个字节一个值),然后通过执行位移操作来使用各个值。
你可以这样做:
using System;
public class Program
{
public static void Main()
{
uint pos = 0x4a5b6c7d;
// x is first byte, y is second byte, z is third byte, matId is fourth byte
uint x = (pos & 0xff);
uint y = (pos & 0xff00) >> 8;
uint z = (pos & 0xff0000) >> 16;
uint matId = (pos & (0xff << 24)) >> 24;
Console.WriteLine(x + " " + y + " " + z + " " + matId);
Console.WriteLine((0x7d) + " " + (0x6c) + " " + (0x5b) + " " + (0x4a));
}
}
x
将等于 0x4a5b6c7d & 0x000000ff
= 0x7d
的结果
y
将等于 0x4a5b6c7d & 0x0000ff00
右移 8 位的结果 = 0x6c
z
和 matId
相似。
编辑
打包需要使用|
运算符:
- 将第四个值左移 24,比如
a
- 将第三个值左移 16,比如
b
- 将第二个值左移 8,比如
c
- 没有第四个值,比如
d
- 对所有 4 个进行二进制或运算并将其存储在
int
中:int packed = a | b | c | d
using System;
public class Program
{
static void Unpack(uint p)
{
uint pos = p;
// x is first byte, y is second byte, z is third byte, matId is fourth byte
uint x = (pos & 0xff);
uint y = (pos & 0xff00) >> 8;
uint z = (pos & 0xff0000) >> 16;
uint matId = (pos & (0xff << 24)) >> 24;
Console.WriteLine(x + " " + y + " " + z + " " + matId);
}
static uint Pack(int x, int y, int z, int matId)
{
uint newx = x, newy = y, newz = z, newMaxId = matId;
uint pos2 = (newMaxId << 24) | (newz << 16) | (newy << 8) | newx;
Console.WriteLine(pos2);
return pos2;
}
public static void Main()
{
uint packedInt = Pack(10, 20, 30, 40);
Unpack(packedInt);
}
}
正如标题所说,我一直在尝试使用 BitShifting 在 c# 中将 4 个完整的 0-255 字节打包成 1 个整数。我正在尝试压缩一些数据,目前使用 40 字节的数据。但实际上理论上我只需要 12 个字节,但为此我需要将所有数据压缩为 3 个整数。
目前我的数据是:
float3 pos; // Position Relative to Object
float4 color; // RGB is Compressed into X, Y is MatID, Z and W are unused
float3 normal; // A simple Normal -1 to 1 range
但理论上我可以压缩到:
int pos; // X, Y, Z, MatID - These are never > 200 nor negative
int color; // R, G, B, Unused Fourth Byte
int normal; // X, Y, Z, [0, 255] = [-1, 1] with 128 being 0, Unused Fourth Byte Should be plenty accurate for my needs
所以我的问题是我该怎么做?我对 Bit Shifting 相当陌生,还没有设法完成很多工作。
如果我没理解错的话,你需要在 4 个字节中存储 4 个值(每个字节一个值),然后通过执行位移操作来使用各个值。
你可以这样做:
using System;
public class Program
{
public static void Main()
{
uint pos = 0x4a5b6c7d;
// x is first byte, y is second byte, z is third byte, matId is fourth byte
uint x = (pos & 0xff);
uint y = (pos & 0xff00) >> 8;
uint z = (pos & 0xff0000) >> 16;
uint matId = (pos & (0xff << 24)) >> 24;
Console.WriteLine(x + " " + y + " " + z + " " + matId);
Console.WriteLine((0x7d) + " " + (0x6c) + " " + (0x5b) + " " + (0x4a));
}
}
x
将等于 0x4a5b6c7d & 0x000000ff
= 0x7d
y
将等于 0x4a5b6c7d & 0x0000ff00
右移 8 位的结果 = 0x6c
z
和 matId
相似。
编辑
打包需要使用|
运算符:
- 将第四个值左移 24,比如
a
- 将第三个值左移 16,比如
b
- 将第二个值左移 8,比如
c
- 没有第四个值,比如
d
- 对所有 4 个进行二进制或运算并将其存储在
int
中:int packed = a | b | c | d
using System;
public class Program
{
static void Unpack(uint p)
{
uint pos = p;
// x is first byte, y is second byte, z is third byte, matId is fourth byte
uint x = (pos & 0xff);
uint y = (pos & 0xff00) >> 8;
uint z = (pos & 0xff0000) >> 16;
uint matId = (pos & (0xff << 24)) >> 24;
Console.WriteLine(x + " " + y + " " + z + " " + matId);
}
static uint Pack(int x, int y, int z, int matId)
{
uint newx = x, newy = y, newz = z, newMaxId = matId;
uint pos2 = (newMaxId << 24) | (newz << 16) | (newy << 8) | newx;
Console.WriteLine(pos2);
return pos2;
}
public static void Main()
{
uint packedInt = Pack(10, 20, 30, 40);
Unpack(packedInt);
}
}