- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
过去我不得不这样做很多次,但我对结果从未感到满意。
谁能建议一种将连续位数组从源复制到目标的快速方法,其中源和目标可能未在方便的处理器边界上对齐(右移)?
如果源和目标都没有对齐,问题可以很快变成只有其中一个没有对齐(在第一个副本之后)。
作为起点,我的代码最终不可避免地看起来像下面这样(未经测试,忽略副作用,这只是一个即兴的例子):
const char mask[8] = { 1, 3, 7, 15, 31, 63, 127, 255 };
/* Assume:
* - destination is already zeroed,
* - offsets are right shifts
* - bits to copy is big (> 32 say)
*/
int bitarray_copy(char * src, int src_bit_offset, int src_bit_len,
char * dst, int dst_bit_offset) {
if (src_bit_offset == dst_bit_offset) { /* Not very interesting */
} else {
int bit_diff_offset = src_bit_offset - dst_bit_offset; /* assume positive */
int loop_count;
char c;
char mask_val = mask[bit_diff_offset];
/* Get started, line up the destination. */
c = (*src++ << bit_diff_offset) | ((*src >> (8 - bit_diff_offset)) & mask_val);
c &= mask[8-dst_bit_offset];
*dst++ |= c;
src_bit_len -= 8 - dst_bit_offset;
loop_count = src_bit_len >> 3;
while (--loop_count >= 0)
* dst ++ = (*src++ << bit_diff_offset) | ((*src >> (8 - bit_diff_offset)) & mask_val);
/* Trailing tail copy etc ... */
if (src_bit_len % 8) /* ... */
}
}
(其实这个比我之前做的好多了,看起来还不错)
最佳答案
这就是我最终所做的。 (编辑 于 2014 年 8 月 21 日更改为单个位复制错误。)
#include <limits.h>
#include <string.h>
#include <stddef.h>
#define PREPARE_FIRST_COPY() \
do { \
if (src_len >= (CHAR_BIT - dst_offset_modulo)) { \
*dst &= reverse_mask[dst_offset_modulo]; \
src_len -= CHAR_BIT - dst_offset_modulo; \
} else { \
*dst &= reverse_mask[dst_offset_modulo] \
| reverse_mask_xor[dst_offset_modulo + src_len]; \
c &= reverse_mask[dst_offset_modulo + src_len]; \
src_len = 0; \
} } while (0)
static void
bitarray_copy(const unsigned char *src_org, int src_offset, int src_len,
unsigned char *dst_org, int dst_offset)
{
static const unsigned char mask[] =
{ 0x00, 0x01, 0x03, 0x07, 0x0f, 0x1f, 0x3f, 0x7f, 0xff };
static const unsigned char reverse_mask[] =
{ 0x00, 0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc, 0xfe, 0xff };
static const unsigned char reverse_mask_xor[] =
{ 0xff, 0x7f, 0x3f, 0x1f, 0x0f, 0x07, 0x03, 0x01, 0x00 };
if (src_len) {
const unsigned char *src;
unsigned char *dst;
int src_offset_modulo,
dst_offset_modulo;
src = src_org + (src_offset / CHAR_BIT);
dst = dst_org + (dst_offset / CHAR_BIT);
src_offset_modulo = src_offset % CHAR_BIT;
dst_offset_modulo = dst_offset % CHAR_BIT;
if (src_offset_modulo == dst_offset_modulo) {
int byte_len;
int src_len_modulo;
if (src_offset_modulo) {
unsigned char c;
c = reverse_mask_xor[dst_offset_modulo] & *src++;
PREPARE_FIRST_COPY();
*dst++ |= c;
}
byte_len = src_len / CHAR_BIT;
src_len_modulo = src_len % CHAR_BIT;
if (byte_len) {
memcpy(dst, src, byte_len);
src += byte_len;
dst += byte_len;
}
if (src_len_modulo) {
*dst &= reverse_mask_xor[src_len_modulo];
*dst |= reverse_mask[src_len_modulo] & *src;
}
} else {
int bit_diff_ls,
bit_diff_rs;
int byte_len;
int src_len_modulo;
unsigned char c;
/*
* Begin: Line things up on destination.
*/
if (src_offset_modulo > dst_offset_modulo) {
bit_diff_ls = src_offset_modulo - dst_offset_modulo;
bit_diff_rs = CHAR_BIT - bit_diff_ls;
c = *src++ << bit_diff_ls;
c |= *src >> bit_diff_rs;
c &= reverse_mask_xor[dst_offset_modulo];
} else {
bit_diff_rs = dst_offset_modulo - src_offset_modulo;
bit_diff_ls = CHAR_BIT - bit_diff_rs;
c = *src >> bit_diff_rs &
reverse_mask_xor[dst_offset_modulo];
}
PREPARE_FIRST_COPY();
*dst++ |= c;
/*
* Middle: copy with only shifting the source.
*/
byte_len = src_len / CHAR_BIT;
while (--byte_len >= 0) {
c = *src++ << bit_diff_ls;
c |= *src >> bit_diff_rs;
*dst++ = c;
}
/*
* End: copy the remaing bits;
*/
src_len_modulo = src_len % CHAR_BIT;
if (src_len_modulo) {
c = *src++ << bit_diff_ls;
c |= *src >> bit_diff_rs;
c &= reverse_mask[src_len_modulo];
*dst &= reverse_mask_xor[src_len_modulo];
*dst |= c;
}
}
}
}
关于c - 什么是复制未对齐位数组的高效算法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3534535/
假设我得到了两个整数 a, b 其中 a 是一个正整数并且小于 b 。我必须找到一种有效的算法,它会在 [a, b] 区间内给出 base2 位数(位数)的总和。例如,在区间 [0, 4] 中,数字之
到目前为止我已经尝试过不同的 autofilter但非选项似乎对我有用,我有许可证号列,其中应该只有 10 位数字,并且 autofilter我正在尝试查找少于或多于 10 位数字的条目, 我将该列转
谁能告诉我检查输入的数字是否为 3 位数字的正则表达式...它也不应该允许字母.... 最佳答案 3 个数字的正则表达式为 ^[0-9]{3}$ 或 ^\d{3}$ 关于javascript - 是否
我不知道这在 SQL Server 中是否可行,但我得问问它 ;-) 我在表 work 中有一个名为 duty 的列。 假设 Work.Duty 包含不同的数字,例如 (1, 2, 3, 20, 22
我正在运行一个我创建的java程序,它存储用户输入的数据。具体来说,有 4 个数组列表,分别是songName、songArtist、songYear 和songAlbum。我有一个“songYear
我不知道这在 SQL Server 中是否可行,但我得问问它 ;-) 我在表 work 中有一个名为 duty 的列。 假设 Work.Duty 包含不同的数字,例如 (1, 2, 3, 20, 22
给定一个 float ,我想使用半偶数舍入将结果四舍五入到小数点后四位,即四舍五入到下一个偶数的方法。例如,当我有以下代码片段时: #include #include int main(){
有没有一种方法可以在不使用小程序的情况下确定客户端计算机上的 jvm 位数?我确实看到了这个link但这决定了 jvm 版本而不是位数。提前致谢 最佳答案 您可以尝试确定浏览器位数 - 32 位 ja
我正在编写一个程序来计算给定数字的两个二进制表示之间的共同位数。我写的代码是: int common_bits(int a, int b) { static long binaryNo1,binary
如何使表格中的每个单元格的最小宽度为 3 位数字并且不会更大?现在我正在对 min-width 进行硬编码,但我不喜欢对值进行硬编码,因为将来我可能想更改字体。如果需要 Javascript 也没关系
我正在尝试匹配后跟一个空格或制表符和 5 个数字的单词。例如 some noise text off 12345 some noise text again. 另一个例子是: Some noise t
我在从 double 到 string 的转换时遇到问题。 我要转换: double value: 0.0772486324655191 string value: 0.077248632465519
我正在尝试实现一个使用 128 位 key 的密码。 key 计划的一部分是将 key 向右旋转 29 位,但我不确定该怎么做,因为 Java 中没有单一数据类型可以保存整个 key 。我将它存储在两
我正在尝试在 AVX2 中对 128 位数进行左旋转。由于没有直接的方法,我尝试使用左移和右移来完成我的任务。 这是我执行相同操作的代码片段。 l = 4; r = 4
我有一个 int,它的值类似于 1235 和 12890。我只想要这个 int 的前 2 位数字。我怎样才能提取它? 想了半天,想不出什么办法。 最佳答案 减少数字,直到只剩下两位数: while (
TL:DR 我想要紧跟“+”符号的任何行上的前两个数字的语法。 给定以下文本(来自熟悉的实用程序): power_meter-acpi-0 Adapter: ACPI interface power1
因此根据 cplusplus.com,当您通过以下方式将输出流的格式标志设置为科学记数法时 of.setf(ios::scientific) 您应该在指数中看到 3 位加号和一个符号。但是,我的输出似
这个问题在这里已经有了答案: How can I pad a value with leading zeros? (77 个答案) 关闭 9 年前。 如果小时数小于 10 小时,则小时数通常以个位数
我正在使用 moment.js使用根据距离/速度计算的日期时间。我也在使用 moment duration format plugin .当我将值传递给 moment.duration 然后对其进行格
我正在将一个应用程序从 .NET 移植到 Mono 运行时,并且在代码中的某个位置我可以看到一个 float 具有值 158136.422。我对 float 的理解是它是 7 位精度,那么这个数字如何
我是一名优秀的程序员,十分优秀!