在计算其位后,宏不会将预期值分配给变量

时间:2017-02-14 18:09:46

标签: c bitwise-operators

我需要编写一个宏np.reshape(data,(5000,3,32,32))来计算两个变量中的所有零,然后确定哪个变量有更多的零并将其分配给结果变量。如果要比较的两个变量具有相同的零数,则第一个变量将分配给结果。 例如,如果maxBitsOffmaxBitsOff(a, b, result, z) a = 1肯定会获得b = 30,因为a中的零比1中的零多。因此,我们将30分配给a,将零数分配给result。 经过几个小时的删除后,我无法让宏工作。这是C:

中的代码
z

运行此代码后,我得到的结果显然很糟糕:

#include <stdio.h> #include <ctype.h> #include <stdlib.h> #include <limits.h> #include "math.h" #define ARR_LEN 8 #define maxBitsOff(a, b, result, z) { \ int acount = 0, bcount = 0, i; \ printf("sizeof(a) = %d\n", sizeof(a)); \ for(i = 0; i < 8 * sizeof(a); i++) { \ if(!(a & (1 << i))) { \ acount++; \ } \ if(!(b & (1 << i))) { \ bcount++; \ } \ } \ if(acount >= bcount) { \ result = a; \ z = acount; \ } else { \ result = b; \ z = bcount; \ } \ printf("result = %d\n", result); \ printf("z = %d\n", z); \ } int main() { int arr[ARR_LEN] = {120, 30, 40, 50, 60, 70, 80, 1}; int z, i, max = 0; int result; for(i = 0; i < ARR_LEN - 1; i++) { maxBitsOff(arr[i], arr[i + 1], result, z); if(max < result) max = result; } return 0; }

result = 32767

4 个答案:

答案 0 :(得分:3)

宏替换是文本替换

您在宏中使用变量i,并将arr[i]作为参数传入。尝试在隐藏的变量名称中使用下划线。另外,将A和B args存储在块中的临时存储中。

答案 1 :(得分:2)

由于 let file: AVAudioFile! do { file = try AVAudioFile(forReading: mySourceURL!) } catch { print("Error:", error) return } let totSamples = file.length let format = AVAudioFormat(commonFormat: .pcmFormatFloat32, sampleRate: file.fileFormat.sampleRate, channels: 1, interleaved: false) let buffer = AVAudioPCMBuffer(pcmFormat: format, frameCapacity: AVAudioFrameCount(totSamples)) try! file.read(into: buffer) var floatArray = Array(UnsafeBufferPointer(start: buffer.floatChannelData?[0], count:Int(buffer.frameLength))) ARR_LEN,并且您的8循环从for迭代到0,因此您正在读取输入数组的末尾。

为什么呢?因为您正在使用宏。

考虑扩展宏时会发生什么:

31

答案 2 :(得分:1)

这主要是为了解决另一个答案,但这是获得位数的更快方法:

#define BC_OffBitCount(in, out)                                \
  {                                                            \
    out = ~in;                                                 \
    switch (sizeof(in)) {                                      \
      case 4:                                                  \
        out = (out & 0x55555555) + ((out >> 1) & 0x55555555);  \
        out = (out & 0x33333333) + ((out >> 2) & 0x33333333);  \
        out = (out & 0x0F0F0F0F) + ((out >> 4) & 0x0F0F0F0F);  \
        out = (out & 0x00FF00FF) + ((out >> 8) & 0x00FF00FF);  \
        out = (out & 0x0000FFFF) + ((out >> 16) & 0x0000FFFF); \
        break;                                                 \
      case 2:                                                  \
        out = (out & 0x5555) + ((out >> 1) & 0x5555);          \
        out = (out & 0x3333) + ((out >> 2) & 0x3333);          \
        out = (out & 0x0F0F) + ((out >> 4) & 0x0F0F);          \
        out = (out & 0x00FF) + ((out >> 8) & 0x00FF);          \
        break;                                                 \
      case 1:                                                  \
        out = (out & 0x55) + ((out >> 1) & 0x55);              \
        out = (out & 0x33) + ((out >> 2) & 0x33);              \
        out = (out & 0x0F) + ((out >> 4) & 0x0F);              \
        break;                                                 \
    }                                                          \
  }

#define BC_OffCompareGreater(a, b, out)  // Left as an exercise to the reader

测试:

void test_uint8_t_of_0x00_should_return_8(void) {
  uint8_t value = 0;
  uint8_t result;
  BC_OffBitCount(value, result);
  TEST_ASSERT_EQUAL(8, result);
}

void test_uint8_t_of_0x55_should_return_4(void) {
  uint8_t value = 0x55;
  uint8_t result;
  BC_OffBitCount(value, result);
  TEST_ASSERT_EQUAL(4, result);
}

void test_uint16_t_of_0xAA_should_return_12(void) {
  uint16_t value = 0xAA;
  uint16_t result;
  BC_OffBitCount(value, result);
  TEST_ASSERT_EQUAL(12, result);
}

void test_uint32_t_of_0xDEADBEEF_should_return_8(void){
    uint32_t value = 0xDEADBEEF;
    uint32_t result;
    BC_OffBitCount(value, result);
    TEST_ASSERT_EQUAL(8, result);
}

我确信这是一种巧妙的方法来消除重复,但这也可以作为练习留给读者。

编辑:我复制并修改了hacker's delight中的代码。

答案 3 :(得分:0)

因为我假设你把它作为一个宏来避免函数调用的开销,所以这里有一个非常快的宏来计算单个值中的位。

我认为这可以作为你想要比较的基础:

#define bitsOffMacro(x, cnt) do {     \
    int _x = x;                        \
    cnt = 32;                           \
    while(_x & -_x){--cnt;_x&=~(_x&-_x);}\
    } while(0)

流程概要:

  • 以32个零开始计数器(假设为4个字节的int)
  • 虽然仍然在值
  • 中找到了一点
  • 减少柜台,因为我们发现了一点。
  • 关掉那个位
  • 重复直到所有位都关闭。

然后使用该宏创建:

#define getHigherCount(x,y,cnt) do {           \
    int _Xcnt;             int _Ycnt;           \
    bitsOffMacro(x,_Xcnt); bitsOffMacro(y,_Ycnt);\
    cnt = (_Xcnt > _Ycnt)?_Xcnt:_Ycnt;            \
} while(0)

样本使用

int cnt;
getHigherCount(23, 4, cnt);
printf("Answer is %d\n", cnt); // expected value 31.

// 23 has 4 bits set, and 28 off.
// 4  has 1 bit set, and 31 off.

<强> P.S。

我将我的宏包装在do-while(0)中有两个原因:

  1. 这样他们必须在使用时用分号调用;否则你在while(0)之后会丢失分号。
  2. 它会创建一个“范围”,我可以在其中创建新变量,例如_x_Xcnt_Ycnt