我有一个字符数组和指向它的指针。我需要将第一个8Bytes(8字节的二进制值)添加到第二个8字节模2exp(64)。我怎么能这样做?
我找到了解决方案。但做这些事情肯定不好(见代码)。然而,将结果放在chars数组中会很好。
void init(const unsigned char *k) {
uint64_t *kp = k;
uint64_t sum = (*kp + *(kp+1)) % pow(2,64)
}
感谢您的帮助
答案 0 :(得分:8)
您不需要% pow(2,64)
,实际上它会引入错误,因为它会将结果转换为double
。类型uint64_t
中的算术已经模2 ^ 64。
将8个字节作为uint64_t
读取的问题基本上是关于您希望它处理的C实现,以及char数组中8个字节的格式。
如果你知道char数组中的8个字节与系统具有相同的字节序(即,如果你的系统是big-endian,那么最重要的字节是第一个,如果你的系统是little-endian,那么最重要的字节是最后的),那你正在做的事情可能还可以。但是,如果系统上存在uint64_t
的对齐限制,那么提供缓冲区的人必须确保它已正确对齐。
如果数据来自某个文件或互联网,那么字节序可能与系统不匹配,并且可能无法正确对齐。
如果8个字节是little-endian,那么这个代码在big-endian系统上会失败,所以如果你想让你的代码可移植,你就必须做其他事情。有些系统unit64_t
不占用8个字节,甚至memcpy
也不起作用。函数的规范可能意味着它完全不适用于这样的系统,但在某些情况下,将8个char的数组转换为uint64_t
是有意义的,无论实际CHAR_BIT是否大于8。
对于可靠的基本解决方案:一次读取一个字节并将各部分相加(左移0,然后8,依此类推)。如果您不喜欢这种情况,请对您需要支持和优化的平台做出一些假设。
但是,如果您希望将结果返回到char数组中,那么您将读取数据,然后反转该过程 - 对于您的代码,*((uint64_t*)output_buffer) = kp[0] + kp[1];
。
答案 1 :(得分:1)
我很确定2pow64模数自然是出于数据的精度(在这种情况下为64位)
所以创建2个变量整数,64位精度,无符号。叫a,和b。
并将前4个字节移动到a, 4个下一个字节进入b, 添加到b。
实际上你不需要做模数。
答案 2 :(得分:0)
问题是对齐。可能是整数指针必须在您的平台上正确对齐;强大的解决方案是简单地将您的字节复制到临时变量中。
void init(const unsigned char *k) {
uint64_t a, b; // two local variables
memcpy(&a,k,8); // fill them up
memcpy(&b,k+8,8); // you presumably mean k+8?
uint64_t sum = a + b;
// do something with sum
}
您可能还需要考虑结束;看看64 bit ntohl() in C++?