【发布时间】:2021-03-04 07:45:54
【问题描述】:
所以我使用以下代码:
unsigned long replaceByte(unsigned long original,unsigned char newByte,int indexToReplace)
{
int shift = 8 * indexToReplace;
unsigned long value = newByte << shift;
unsigned long mask = 0xff << shift;
return (~mask & original) | value;
}
我有一个带有 |w| 的单词字节。
- 字节从 0(最不重要)到 w/8-1(最重要 重要)。
例如:
replaceByte(unsigned long original, unsigned char newByte, int indexToReplace)
correct answer:
replaceByte(0x12345678CDEF3456, 0xAB, 2) --> 0x1234AB78CDEF3456
(my code's output is: 0x12345678CDAB3456)
correct answer:
replaceByte(0x12345678CDEF3456, 0xAB, 0) --> 0xAB345678CDEF3456
(my code's output is: 0x12345678cdef34AB)
我认为我需要检查系统是大端还是小端,因为我的代码更改了完全相反的字节。例如,它改变了 MSB 而不是 LSB。 但是......我意识到这并不重要,因为我正在使用比特。
如您所见,这里的代码更改了错误的索引:
(!) Error in index: 0. Output: 0x123456789abcdeff
Answer: 0xff3456789abcdeab
(!) Error in index: 1. Output: 0x123456789abcffab
Answer: 0x12ff56789abcdeab
(!) Error in index: 2. Output: 0x123456789affdeab
Answer: 0x1234ff789abcdeab
(!) Error in index: 3. Output: 0xffffffffffbcdeab
Answer: 0x123456ff9abcdeab
(!) Error in index: 4. Output: 0x123456789abcdeff
Answer: 0x12345678ffbcdeab
(!) Error in index: 5. Output: 0x123456789abcffab
Answer: 0x123456789affdeab
(!) Error in index: 6. Output: 0x123456789affdeab
Answer: 0x123456789abcffab
好吧,我考虑将我的代码更改为带有数组的东西,只是为了获得一个数字 -> 作为数组在其上运行 -> 更改所需的索引 -> 就是这样。 但是..我不能正确地写它所以我坚持移动的东西(我也不能正确地写)。 这是我的尝试:
unsigned long replaceByte(unsigned long original, unsigned char newByte, int indexToReplace){
int size = (sizeof(unsigned long));
char a[size];
for (int i=0; i<size; i++){
if (i=0)
a[0] = original & 0xff;
else
a[i] = original>>(8*i) & 0xff;
}
a[indexToReplace] = newByte;
......// stuck
}
我不允许使用 long long、uint_fast64_t 或 reinterpret_cast 或任何其他“外部”东西。
如果代码在 32 位系统或 64 位系统上运行,我还认为我需要以某种方式进行更改,以确定哪个大小是 unsigned long(4 或 8 字节)。
【问题讨论】:
-
您应该删除一个不太必要的标签,并用您的编程语言标记您的问题。这将确保它被最多可能能够回答它的用户看到。
-
首先,
mask和value是int。它们截断了值并且需要为unsigned long(与original相同的类型)。 -
在 64 位系统上工作,因为
long是 64 位的。对于 32 位系统,请使用unsigned long long。这适用于 32 和 64 -
尝试
0xffL而不是0xff。由于提升规则,后者将执行 32 位移位和截断。修复强制 64 位 -
@DimaCiun 字节序在这里完全无关,因为它是值在内存中存储的方式。由于您没有任何指针并且只是对值进行操作,因此字节序不会影响结果
标签: c bit-manipulation byte bitmask byte-shifting