访问数组中的每个第 n 个元素(汉明代码)
accessing every nth element in array (hamming code)
所以基本上我正在创建一个程序,提示用户输入像 'A' 这样的字符,它 returns 它们根据 ASCII 图表的二进制值,在这种情况下是 01000001。什么应该输出的是一个12位的汉明码序列,有8个数据位和4个奇偶校验位。我遇到的问题是想出一种方法将正确的数据位插入到基本上不是 2 的幂的每个数组位置。我应该提到数组的类型是 char。
所以它应该打印出来:_ _ 0 _ 1 0 0 _ 0 0 0 1 空格代表奇偶校验位的位置。现在我的代码只打印出 000001000001(到目前为止还没有确定奇偶校验值)但我想不出一种方法将 8 个数据位中的每一个都定位到非奇偶校验位位置。
我假设我必须编辑我的 for 循环,它目前涉及 for(int i = 12; i >= 0; i--) 但我似乎无法找出我可以使用的数学模式。我不确定我目前的方法是否可行。任何提示或帮助将不胜感激。
下面基本上只是我正在努力处理的代码部分的粗略概述:
for (int i=12; i>=0; i--) {
if ((int)(n/pow(2,i)) > 0) {
//index = 1
n = n - pow(2,i);
}
else
//index = 0
}
您需要熟悉的操作是掩码和移位。 不要使用pow
进行位操作。这是一个大型的重量级函数,用于数值计算。
有几种方法可以生成您寻求的 _ _ 0 _ 1 0 0 _ 0 0 0 1
模式。一种是先清除最右边的space。如果 x
保留原始值 0100001
,则第一步是屏蔽除最后 4 位以外的所有位。这是x & 0xfu
。 &
是合乎逻辑的 "and." 所有其他位都可以用 x & ~0xfu
屏蔽掉。 ~
是按位 "not." 现在你想将这些其他位左移一位并使用 "or" 将它们与低位 4 位组合。所以我们总共有:
unsigned x = 'A';
unsigned a = (x & 0xfu) | ((x & ~0xfu) << 1);
要将最上面的位向左移动一位,遵循相同的步骤,只是现在您希望最右边的 8 位保持原位,而第 9 位和更高位移动一个在左边。你需要的面具是0xffu
。所以我们最终得到
unsigned result = (a & 0xffu) | ((a & ~0xffu) << 1);
现在您可以 "or" 在奇偶校验位中,然后用类似的东西打印出按位表示:
for (unsigned m = 0x800; m; m >>= 1) printf("%d", (m & result) != 0);
同样,0x800
是第 11 位的掩码。您可以使用它来检查 (m & result) != 0
结果的第 11 位。如果设置了 result
的相应位,则此值为 1,否则为 0,正是您要打印的内容。 for
循环的每次连续迭代都会将掩码向右移动一位。当位完全移出时,循环停止。这发生在 12 次迭代之后,所以你打印 12 位,这似乎是你想要的。
注意我一直使用无符号类型。这在这里不是绝对必要的,但使用无符号类型进行位操作通常不太容易出错,因为符号扩展会导致意外结果。
总而言之,您可以使用 0xff
作为输入进行测试,以查看奇偶校验位所属的 "holes":
#include <stdio.h>
int main(void)
{
unsigned x = 0xffu;
unsigned a = (x & 0xfu) | ((x & ~0xfu) << 1);
unsigned result = (a & 0xffu) | ((a & ~0xffu) << 1);
for (unsigned m = 0x800; m; m >>= 1)
printf("%d", (m & result) != 0);
return 0;
}
如您所愿打印 001011101111
。
有很多有趣的细节需要解决。我让给你。
所以基本上我正在创建一个程序,提示用户输入像 'A' 这样的字符,它 returns 它们根据 ASCII 图表的二进制值,在这种情况下是 01000001。什么应该输出的是一个12位的汉明码序列,有8个数据位和4个奇偶校验位。我遇到的问题是想出一种方法将正确的数据位插入到基本上不是 2 的幂的每个数组位置。我应该提到数组的类型是 char。
所以它应该打印出来:_ _ 0 _ 1 0 0 _ 0 0 0 1 空格代表奇偶校验位的位置。现在我的代码只打印出 000001000001(到目前为止还没有确定奇偶校验值)但我想不出一种方法将 8 个数据位中的每一个都定位到非奇偶校验位位置。
我假设我必须编辑我的 for 循环,它目前涉及 for(int i = 12; i >= 0; i--) 但我似乎无法找出我可以使用的数学模式。我不确定我目前的方法是否可行。任何提示或帮助将不胜感激。
下面基本上只是我正在努力处理的代码部分的粗略概述:
for (int i=12; i>=0; i--) {
if ((int)(n/pow(2,i)) > 0) {
//index = 1
n = n - pow(2,i);
}
else
//index = 0
}
您需要熟悉的操作是掩码和移位。 不要使用pow
进行位操作。这是一个大型的重量级函数,用于数值计算。
有几种方法可以生成您寻求的 _ _ 0 _ 1 0 0 _ 0 0 0 1
模式。一种是先清除最右边的space。如果 x
保留原始值 0100001
,则第一步是屏蔽除最后 4 位以外的所有位。这是x & 0xfu
。 &
是合乎逻辑的 "and." 所有其他位都可以用 x & ~0xfu
屏蔽掉。 ~
是按位 "not." 现在你想将这些其他位左移一位并使用 "or" 将它们与低位 4 位组合。所以我们总共有:
unsigned x = 'A';
unsigned a = (x & 0xfu) | ((x & ~0xfu) << 1);
要将最上面的位向左移动一位,遵循相同的步骤,只是现在您希望最右边的 8 位保持原位,而第 9 位和更高位移动一个在左边。你需要的面具是0xffu
。所以我们最终得到
unsigned result = (a & 0xffu) | ((a & ~0xffu) << 1);
现在您可以 "or" 在奇偶校验位中,然后用类似的东西打印出按位表示:
for (unsigned m = 0x800; m; m >>= 1) printf("%d", (m & result) != 0);
同样,0x800
是第 11 位的掩码。您可以使用它来检查 (m & result) != 0
结果的第 11 位。如果设置了 result
的相应位,则此值为 1,否则为 0,正是您要打印的内容。 for
循环的每次连续迭代都会将掩码向右移动一位。当位完全移出时,循环停止。这发生在 12 次迭代之后,所以你打印 12 位,这似乎是你想要的。
注意我一直使用无符号类型。这在这里不是绝对必要的,但使用无符号类型进行位操作通常不太容易出错,因为符号扩展会导致意外结果。
总而言之,您可以使用 0xff
作为输入进行测试,以查看奇偶校验位所属的 "holes":
#include <stdio.h>
int main(void)
{
unsigned x = 0xffu;
unsigned a = (x & 0xfu) | ((x & ~0xfu) << 1);
unsigned result = (a & 0xffu) | ((a & ~0xffu) << 1);
for (unsigned m = 0x800; m; m >>= 1)
printf("%d", (m & result) != 0);
return 0;
}
如您所愿打印 001011101111
。
有很多有趣的细节需要解决。我让给你。