c - C中的位操作出错

标签 c bit-manipulation

我正在尝试在C语言中进行一些操作。到目前为止,我所做的一切都是正确的,但最终测试表明存在错误。对我来说,功能看起来不错,但是...输出与预期不同。

#include <stdint.h>

#include "PETER_interface.h"

const int BITS_IN_BYTE = 8;
static int g_capacity = 0;
static int g_size = 0;
static container_id_t indexOfTable = 0;

uint8_t* storages[4] = {0 ,0 ,0 ,0};

err_t PETER_new(container_id_t* id, int num_of_bits) {
    storages[indexOfTable] = (uint8_t*)(malloc((num_of_bits / BITS_IN_BYTE) 
    + (num_of_bits % BITS_IN_BYTE) ? 1 : 0));

    g_capacity = num_of_bits;
    g_size = ((num_of_bits / BITS_IN_BYTE) + (num_of_bits % BITS_IN_BYTE) ? 
1 : 0);

    *id = indexOfTable;

    indexOfTable++;

    return E_OK;
}

err_t PETER_resize(container_id_t id, int bit) {
    return E_NOT_IMPLEMENTED;
}

err_t PETER_delete(container_id_t id) {
    return E_NOT_IMPLEMENTED;
}

err_t PETER_deleteAll() {
    return E_NOT_IMPLEMENTED;
}

err_t PETER_set(container_id_t id, int bit) {
    uint8_t temp =  *(storages[id]) / BITS_IN_BYTE;

    temp |= (1 << (bit % BITS_IN_BYTE));

    *(storages[id]) = temp;

    return E_OK;
}

err_t PETER_clear(container_id_t id, int bit) {
    uint8_t temp =  *(storages[id]) / BITS_IN_BYTE;

    temp &= ~(1 << (bit % BITS_IN_BYTE));

    *(storages[id]) = temp;

    return E_OK;
}

err_t PETER_invert(container_id_t id, int bit) {    
    uint8_t temp =  *(storages[id]) / BITS_IN_BYTE;

    temp ^= (1 << (bit % BITS_IN_BYTE));

    *(storages[id]) = temp;

    return E_OK;
}

err_t PETER_capacity(container_id_t id, int *capacity) {
    *capacity = g_capacity;

    return E_OK;
}

err_t PETER_storageSize(container_id_t id, int *size) {
    *size = g_size;

    return E_OK;
}

err_t PETER_get(container_id_t id, int flag_no, int *return_value) {    
    *return_value = (*(storages[id]) >> (flag_no % BITS_IN_BYTE)) & 1;

    return E_OK;
}


我的测试如下所示:

    int ok = 1;

    const int size = 8;
    container_id_t id;
    int val;


    OK(  new(&id,size),         E_OK  );

    OK(  capacity(id,    &val), E_OK  );
    OK(  val, size );

    OK(  storageSize(id, &val), E_OK  );
    OK(  val, 1 );

    printf("storageSize: %d\n", val);

    OK(  set(id, 4),            E_OK  );
    OK(  get(id, 4, &val),      E_OK  ); 

    printf("set: %d\n", val);

    OK(  val, 1 );

    OK(  clear(id, 4),          E_OK  );
    OK(  get(id, 4, &val),      E_OK  ); 

    printf("clear: %d\n", val);

    OK(  val, 0 );

    OK(  invert(id, 4),         E_OK  );    
    OK(  get(id, 4, &val),      E_OK  ); 

    printf("invert: %d\n", val);

    OK(  val, 1 );

    OK(  invert(id, 4),         E_OK  );  
    OK(  get(id, 4, &val),      E_OK  ); 

    printf("invert: %d\n", val);

    OK(  val, 0 );


    // not yet implemented
    OK(  resize(id, 2*size),E_NOT_IMPLEMENTED  );
    OK(  delete(id),        E_NOT_IMPLEMENTED  );
    OK(  deleteAll(),       E_NOT_IMPLEMENTED  );



    if(ok == 1) {
        OUT_GREEN();
        printf("%s: ok", module_name);
        OUT_WHITE();
    }


我得到的输出看起来像这样:

Run tests
storageSize: 1
set: 1
clear: 0
invert: 1
invert: 1
fail line 84 (which is second invert)


我正在尝试找出错误所在,但是什么也看不到。也许你们可以看到吗?

最佳答案

您所有的比特旋转功能都在错误地寻址所需的比特,并在工作结束时破坏了存储的值。他们采用以下形式:


    uint8_t temp =  *(storages[id]) / BITS_IN_BYTE;

    // ... perform some operation on temp ...

    *(storages[id]) = temp;



现在观察到,即使省略了所有对temp值的操作,在大多数情况下,最终结果还是对存储值的更改。

我猜想参数bit应该作为在uint8_tstorages[i]序列表示的位数组的索引。然后,您可以改写

    uint8_t temp =  (storages[id])[bit / BITS_IN_BYTE];

    // ... perform some operation on temp ...

    (storages[id])[bit / BITS_IN_BYTE] = temp;


请注意,在这种情况下,指定要从其初始化temp的对象的表达式与指定要记录temp的最终值的对象的表达式如何相同。

关于c - C中的位操作出错,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46795790/

相关文章:

将 unsigned char * 转换为 char * string C

c - GCC编译器: error linker command failed using the Make file

c# - 将 java 方法转换为 C# : converting bytes to integers with bit shift operators

python - 如何在 Python 中优化 str.replace()

c - 使用 fgetc 将数据加载到二维数组中?

c++ - 函数调用性能

c - 单独查看内存中的每一位

language-agnostic - 如何获得跨步模式的校验和

c - c中的按位溢出检查

c++ - PSTR如何接收多个不以逗号分隔的字符串?