将按位运算从 C# 移植到 C

Porting Bitwise Operations from C# To C

我需要一些帮助将此 C# 代码移植到 C。我在 C# 中工作得很好,但我在 C 中遇到了错误 return。我是否应该将位移分解为单独的线?我以为我的数据类型有问题,但我认为我有正确的数据类型。这是 returns 0x03046ABE

的工作代码
  UInt32 goHigh(UInt32 x) { return (UInt32)(x & 0xFFFF0000); }          
  UInt32 goLow(UInt32 x) { return (UInt32)(x & 0xFFFF); } 

  UInt32 magic(UInt32 pass){
      UInt32 key = pass;
      UInt16 num = 0x0563;
      key = (goLow(key) << 16) | (UInt16)(((num >> 3) | (num << 13)) ^ (goHigh(key) >> 16));
      return key; //returns 0x03046ABE

   }

  magic(0x01020304);

这是我正在尝试运行的错误 C 代码

  unsigned long  goHigh(unsigned long  x) { 
         return (unsigned long )(x & 0xFFFF0000); }          
  unsigned long  goLow(unsigned long  x) { 
         return (unsigned long )(x & 0xFFFF); } 

  unsigned long  magic(unsigned long  pass){
      unsigned long key = pass;
      unsigned int num = 0x0563;
      key = (goLow(key) << 16) | (unsigned int)(((num >> 3) | (num << 13)) ^ (goHigh(key) >> 16));
      return key;
  }

  magic(0x01020304); //returns 0xb8c6a8e

最有可能的问题在这里:

key = (goLow(key) << 16) | (unsigned int)(((num >> 3) | (num << 13)) ^ (goHigh(key) >> 16));
                            ^^^^^^^^^^^^

您期望的是 16 位。它在不同的机器上可能更大。与 unsigned long 相同,如您所料,它可能是 64 位而不是 32 位。

为了确定,请使用 uint32_t & uint16_t。您必须 #include <stdint.h> 才能使用它们。

long 和 int 不是您在平台上期望的大小(分别为 32 位和 16 位)

将原始类型替换为实际大小,将得到相同的输出。我还删除了多余的转换。

这些类型可以在 stdint.h

中找到
#include <stdint.h>

    uint32_t  goHigh(uint32_t   x) {
        return (x & 0xFFFF0000);
    }

    uint32_t goLow(uint32_t x) {
        return (x & 0xFFFF);
    }

    uint32_t magic(uint32_t pass) {
        uint32_t  key = pass;
        uint32_t num = 0x0563;
        key = (goLow(key) << 16) | (uint16_t)(((num >> 3) | (num << 13)) ^ (goHigh(key) >> 16));
        return key;
    }