2011-06-14 79 views
3

我有一个char*缓冲区,我想追加各种位大小的整数(在132之间)到。追加1到32位数字到字符缓冲区

因此,我需要一个函数:

void addBits(char *buffer, int bits_appended_so_far, int object, int object_bit_size); 

可以,比方说,13比特的对象移动到缓冲器的第470比特位置。

我当然可以将这些位逐个移动到缓冲区中,但速度是至关重要的,因此似乎应该可以一次移动较大的块。有没有一个标准的方法来做到这一点?似乎应该有一个标准的方法,但一些谷歌搜索和SO搜索没有给我我想要的。

+0

你究竟想达到什么目的? libgmp允许对任意大小的整数进行直接位操作,这可能是存储大字符串的好方法,或者您可以考虑使用'std :: vector '... – 2011-06-14 16:17:39

+0

我看不到矢量会对此有何帮助情况。我不需要动态分配或任何东西。只是一个有效的函数,用于在char数组中添加一个X位大小的对象。 X保证适合int。 – Gurgeh 2011-06-14 16:29:51

+0

'std :: vector '很烂。总有这种感觉,它可以像'std :: vector'一样使用。 – 2011-06-14 16:35:46

回答

2

怎么是这样的:

void addBits(char *buffer, int bits_appended_so_far, int object, int object_bit_size) { 
    int* int_buffer = reinterpret_cast<int*>(buffer); 

    const int bits_per_int = 8 * sizeof(int); 

    int current_int = bits_appended_so_far/bits_per_int; 
    int current_offset = bits_appended_so_far % bits_per_int; 

    int_buffer[current_int] |= object << current_offset; 
    if(current_offset) 
     int_buffer[current_int+1] |= object >> (bits_per_int - current_offset); 
} 

这假定object只设置最低显著object_bit_size位,否则,你需要添加一个步骤砍额外的(不必要的)位关断。它还假定在开始添加位之前缓冲区已初始化为零。

+0

这对我来说已经够好了(+1并且已被接受),尽管一般情况下它不起作用。将一个随机指针转换为int会导致某些体系结构上的总线错误(如果它不是DWORD对齐的)。我曾经在SGI上遇到过这个问题。此外,它假定int对象足够大,可以处理current_offset的左移,但它没问题,但我会用很长的代码(代码在x86_64上运行就足够了)。 – Gurgeh 2011-06-15 09:27:32

+0

谢谢。我想你可以通过将输入int对象分解为char大小的部分,然后分别将每个部分写入char *缓冲区来避免int *强制转换。 (2)移位总是小于int中的位数,所以应该是明确的,所以我不理解你的评论的第二部分。无论如何,希望它能奏效或给你一些想法。 – JohnPS 2011-06-15 20:16:28

0

的最简单的解决方案似乎是使用碱性memcpy和适当地偏移,如果位置没有字节对准

+0

这将打破第一个目标字节的位,但如果我分开处理这个特殊情况,也许这是简单的足够。 – Gurgeh 2011-06-14 16:32:33

+0

好点!它会摧毁你的数据 - 我想你必须移动数据来添加一个临时变量,然后(假设数组已初始化为全0)... 或者将移位的数据转换为临时变量以及每个字节/字的原始数据并覆盖原始部分 – 2011-06-14 16:54:34

0

标准字大小为1,2,4,8和16个字节取决于CPU的,所以可以移一次只有8,16,32,64或128位。没有标准的方法!

如果你不想用内存空间,我的建议是使用最小单位一个字节,而不是一位,以避免位移和加速功能。

编辑: 如果内存是优先级并且位大小在1到32之间,那么仍然没有问题,因为大多数CPU一次支持多于1位的移位。

在x86下,如果您使用的是32位寄存器,则可以一次移动多达32位。

+0

编号内存优先级为1,速度优先级为2,额外的位对我的应用程序确实很重要。 – Gurgeh 2011-06-14 16:40:31

1
  • 使用移位在32位整数中正确对齐位。
  • 查找缓冲区中字节的位置。
  • 如果需要保留缓冲区的内容,请创建一个指向相关字节的int指针,然后按位|该位置的32位int。
  • 如果不需要保存内容,只需memcpy(缓冲区位置,32位int);