将两个数字打包成一个 Int32

Pack two numbers into one Int32

我正在向连接的设备发送数据,但出现了从设备返回的一个整数包含两个 ID 的问题。一个封装在 10 个 LSB 位中,第二个封装在 22 个 MSB 位中。从这个网站的帮助中,我找到了如何解析这两个数字(我相信这是正确的):

//10 LSB bits
var nodeID = source & 0x3FF; //mask 10 LSBs

//22 MSB bits: mask + bitshift
var companyID = (source & 0x3FFFFF) >> 10;

现在我需要从两个数字(分别是 10 位和 22 位)创建一个 int32,并且再次需要一些指导。涉及的步骤是什么?

谢谢!

看来你有

   companyID  nodeID 
   <- 22  ->  <-10->

格式。如果是你的情况,你可以

var nodeID    = source & 0x3FF;            // Rightmost 10 bits: just mask
var companyID = (source >> 10) & 0x3FFFFF; // Move to the right, then mask 

请注意,对于 companyID,您应该先将其向右移动,以便去掉最左边的 10 (nodeID) 位:

初始:

   companyID  nodeID 
   <- 22  ->  <-10->

移位后 ( >> 10):

   sssssssss companyID   
   sign bits <- 22  ->  

屏蔽后 ( & 0x3FFFFF):

   00..00 companyID == companyID  
   <-10-> <- 22  ->

反转:

   var encoded = (CompanyID << 10) | nodeID

我想这就是答案

Value = LSB + (MSB << 10);

它似乎不应该比类似的东西更复杂:

// convenience overload
public static int Pack( int x, int y )
{
  return (int) Pack( (uint)x, (uint)y);
}

// convenience overload 
public static void Unpack( int p, out int x, out int y )
{
  uint x1, y1;
        
  Unpack( (uint)p, out x1, out y1 );
        
  x = (int) x1;
  y = (int) y1;
  
}

// the guts of the pack operation
public static uint Pack( uint x , uint y )
{
  if ( ( x & 0xFFC00000u ) != 0 ) throw new ArgumentOutOfRangeException("argument out of range", "x");
  if ( ( y & 0xFFFFFC00  ) != 0 ) throw new ArgumentOutOfRangeException("argument out of range", "y");
  
  uint z = ( x << 10 ) | ( y & 0x000003FF );
  return z;
}

// the guts of the unpack operation
public static void Unpack( uint p, out uint x , out uint y )
{
  x = ( p & 0xFFFFFC00u ) >> 10 ;
  y = ( p & 0x000003FFu )       ; 
}

// MSB (Most significant bits); From left to right
// LSB (Least significant bits);  From right to left

// 10 LSBits
var result = source1 & 0x3FF;
// 10 MSBits
var result = (source1 >> 22) & 0x3FF;
// 22 LSBits
var result = source2 & 0x3FFFFF;
// 22 MSBits
var result = (source2 >> 10) & 0x3FFFFF;

// 10 LSBits pack with 22 MSBits
var result = ((source1 & 0x3FF) << 22) | ((source2 >> 10) & 0x3FFFFF);
// 10 MSBits pack with 22 LSBits (1'st variation)
var result = (source1 & 0xFFC00000) | (source2 & 0x3FFFFF);
// 10 MSBits pack with 22 LSBits (2'nd variation)
var result = (((source1 >> 22) & 0x3FF) << 22) | (source2 & 0x3FFFFF);
// 10 LSBits pack with 22 LBSBits
var result = ((source1 & 0x3FF) << 22) | (source2 & 0x3FFFFF);
// 10 MSBits pack with 22 MSBits (1'st variation)
var result = (source1 & 0xFFC00000) | ((source2 >> 10) & 0x3FFFFF);
// 10 MSBits pack with 22 MSBits (2'nd variation)
var result = (((source1 >> 22) & 0x3FF) << 22) | ((source2 >> 10) & 0x3FFFFF);

// 22 LSBits pack with 10 MSBits
var result = ((source2 & 0x3FFFFF) << 10) | ((source1 >> 22) & 0x3FF);
// 22 MSBits pack with 10 LSBits (1'st variation)
var result = (source2 & 0xFFFFFC00) | (source1 & 0x3FF);
// 22 MSBits pack with 10 LSBits (2'nd variation)
var result = (((source2 >> 10) & 0x3FFFFF) << 10) | (source1 & 0x3FF);
// 22 LSBits pack with 10 LSBits
var result = ((source2 & 0x3FFFFF) << 10) | (source1 & 0x3FF);
// 22 MSBits pack with 10 MSBits (1'st variation)
var result = (source2 & 0xFFFFFC00) | ((source1 >> 22) & 0x3FF);
// 22 MSBits pack with 10 MSBits (2'nd variation)
var result = (((source2 >> 10) & 0x3FFFFF) << 10) | ((source1 >> 22) & 0x3FF);

Choose which one you like...