将数字拆分为C中的高位和低位

时间:2014-11-04 13:13:08

标签: c labview

我想使用C API将Labview FPGA中的数据发送到C函数。为了使数据传输同步,我执行以下操作:

1)输入:

  • 3x I16值
  • 1x U16值

2)在两个步骤中,我使用Labview中的连接数函数将这4个值打包到U64中(它确实是hi.lo)。所以它基本上是:

((I16.I16).(I16.U16))
(   U32   .   U32   )
         U64

3)现在这个U64值被转移到C函数,它应该像这样解压缩:

         U64
(   U32   .   U32   )
((I16.I16).(I16.U16))

现在我想知道如何在C中处理拆包。在Labview中是否有类似“拆分号”功能的东西?如何确保所有部件都分配了正确的数据类型?

2 个答案:

答案 0 :(得分:5)

不,没有。你通常使用按位运算来做这种事情,主要是移位和掩码:

const uint64_t incoming = 0xfeedcafebabef00d;
const int16_t  first  = (int16_t) (incoming >> 48);
const int16_t  second = (int16_t) ((incoming >> 32) & 0xffff);
const int16_t  third  = (int16_t) ((incoming >> 16) & 0xffff);
const uint16_t fourth = incoming & 0xffff;

这当然假定每个地方的字节顺序都是正确的,并将first设置为0xfeed(十进制为-275),依此类推。

作为一般观察,每次提取所需的实际代码量很少,这可以解释为什么没有通用功能来执行此操作:您不需要它。

如果您愿意,您当然可以写一个:

uint16_t extractU16(uint64_t bits, uint8_t lsbIndex)
{
  return (uint16_t) ((bits >> lsbIndex) & 0xffff);
}

鉴于此,您可以将上述内容重写为:

const int16_t  first  = (int16_t) extractU16(incoming, 48);
const int16_t  second = (int16_t) extractU16(incoming, 32);
const int16_t  third  = (int16_t) extractU16(incoming, 16);
const uint16_t fourth = extractU16(incoming, 0);

我们可以通过extractS16()进一步改进(?)当然返回int16_t,以允许丢弃演员,但我不会打扰。 :)

答案 1 :(得分:1)

还有另一种方法,没有轮班和面具。假设正确的结束:

#pragma pack(1)
union abc {
    struct u {
        int16_t a;
        int16_t b;
        int16_t c;
        uint16_t d;
     } u16;
     uint64_t u64;
 } datum;

 datum.u64 = XXXX; /* Number you got from LV */
 datum.u16.a /* first of the the numbers */

像这样使用它:

  datum.u64=0x112233445566ull;

  printf("%x\n", datum.u16.a);
  printf("%x\n", datum.u16.b);
  printf("%x\n", datum.u16.c);
  printf("%x\n", datum.u16.d);