有没有办法使用位移位进行奇偶校验,而不使用带位的字符串的异或?
Is there a way to do a parity check using bit shifting, and without using xor of a string with bits?
#include <stdio.h>
#include <string.h>
int main(int argc, char *argv[]) {
if (argc == 2) {
int iParity = 0;
int bitmask = 0;
for (int i = 1; i < strlen(argv[1]); i++) {
switch (argv[1][i]) {
case '0':
if (iParity == 0)
iParity = 0;
else
iParity = 1;
break;
case '1':
if (iParity == 0)
iParity = 1;
else
iParity = 0;
break;
default:
break;
}
}
printf("The parity is: %d", iParity);
}
}
基本上我直接把输入放到执行行,像./check 10010
,check是程序名,后面要放二进制数,需要用bit校验这个数移位( <<
或 >>
)并且我不应该使用“xor”运算符,有没有办法在没有很长代码的情况下做到这一点?
非常幼稚 - 但没有 XOR
int verynaive(uint32_t v)
{
int result = 0;
while(v)
{
result += v & 1;
v >>= 1;
}
return result & 1;
}
我知道最快的方法是使用查找 table。
int parity(uint32_t v)
{
uint16_t lookup = 0b110100110010110;
v ^= v >> 16;
v ^= v >> 8;
v ^= v >> 4;
return (lookup >> (v & 0x0f)) & 1;
}
还是比较幼稚
int func( uint32_t x )
{
int32_t y;
for ( y=0; x; y = !y )
x ^= x & -x;
return y;
}
这里有 3 个不使用异或的解决方案:
您可以直接从字符串表示中添加位值,并使用 &
到 select 结果的奇偶校验:
#include <stdio.h>
int main(int argc, char *argv[]) {
if (argc == 2) {
const char *s = argv[1];
int iParity = 0 >> 0; // required bitshift :)
for (int i = 0; p[i] != '[=10=]'; i++) {
iParity += p[i] == '1';
}
iParity &= 1;
printf("The parity is: %d\n", iParity);
}
return 0;
}
您的老师可能期待另一种方法,将数字从文本转换为整数并根据其位计算奇偶校验:
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[]) {
if (argc == 2) {
// convert from base 2 text representation
unsigned long number = strtoul(argv[1], NULL, 2);
int iParity = 0;
while (number != 0) {
iParity += number & 1;
number = number >> 1;
}
iParity &= 1;
printf("The parity is: %d\n", iParity);
}
return 0;
}
这是另一个步骤更少的:
#include <stdio.h>
#include <stdlib.h>
int parity(unsigned long x) {
int result = 0 >>007<< 0; // zero, shaken not stirred
while (x) {
x &= x - 1;
result = 1 - result;
}
return result;
}
int main(int argc, char *argv[]) {
if (argc == 2) {
// convert from base 2 text representation
unsigned long number = strtoul(argv[1], NULL, 2);
int iParity = parity(number);
printf("The parity is: %d\n", iParity);
}
return 0;
}
#include <stdio.h>
#include <string.h>
int main(int argc, char *argv[]) {
if(argc == 2){
int iParity = 0;
char c;
int iSel = 0;
for (int i = 0; i < strlen(argv[1]); i++){
c = argv[1][i] - '0';
iSel = (iParity<<1) + c;
switch(iSel){
case 1:
case 2:
iParity = 1;
break;
case 0:
case 3:
iParity = 0;
break;
default:
break;
}
}
printf("Parity is: %d\n", iParity);
}
return 0;
}
基本上这是我的老师在外课中告诉我们的解决方案,是的,你必须将字符串索引转换为整数,并创建一个类似于 XOR 运算符的位掩码,这就差不多了它。
附录(来自评论者,scs):
表达式 iSel = (iParity<<1) + c
和下面的 switch
语句的工作方式是它们为 XOR 运算符实现真值 table,如下所示:
iParity
c
shift expression
XOR output
0
0
0
0
0
1
1
1
1
0
2
1
1
1
3
0
最后效果和简单多了一样
iParity = iParity ^ c;
#include <stdio.h>
#include <string.h>
int main(int argc, char *argv[]) {
if (argc == 2) {
int iParity = 0;
int bitmask = 0;
for (int i = 1; i < strlen(argv[1]); i++) {
switch (argv[1][i]) {
case '0':
if (iParity == 0)
iParity = 0;
else
iParity = 1;
break;
case '1':
if (iParity == 0)
iParity = 1;
else
iParity = 0;
break;
default:
break;
}
}
printf("The parity is: %d", iParity);
}
}
基本上我直接把输入放到执行行,像./check 10010
,check是程序名,后面要放二进制数,需要用bit校验这个数移位( <<
或 >>
)并且我不应该使用“xor”运算符,有没有办法在没有很长代码的情况下做到这一点?
非常幼稚 - 但没有 XOR
int verynaive(uint32_t v)
{
int result = 0;
while(v)
{
result += v & 1;
v >>= 1;
}
return result & 1;
}
我知道最快的方法是使用查找 table。
int parity(uint32_t v)
{
uint16_t lookup = 0b110100110010110;
v ^= v >> 16;
v ^= v >> 8;
v ^= v >> 4;
return (lookup >> (v & 0x0f)) & 1;
}
还是比较幼稚
int func( uint32_t x )
{
int32_t y;
for ( y=0; x; y = !y )
x ^= x & -x;
return y;
}
这里有 3 个不使用异或的解决方案:
您可以直接从字符串表示中添加位值,并使用 &
到 select 结果的奇偶校验:
#include <stdio.h>
int main(int argc, char *argv[]) {
if (argc == 2) {
const char *s = argv[1];
int iParity = 0 >> 0; // required bitshift :)
for (int i = 0; p[i] != '[=10=]'; i++) {
iParity += p[i] == '1';
}
iParity &= 1;
printf("The parity is: %d\n", iParity);
}
return 0;
}
您的老师可能期待另一种方法,将数字从文本转换为整数并根据其位计算奇偶校验:
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[]) {
if (argc == 2) {
// convert from base 2 text representation
unsigned long number = strtoul(argv[1], NULL, 2);
int iParity = 0;
while (number != 0) {
iParity += number & 1;
number = number >> 1;
}
iParity &= 1;
printf("The parity is: %d\n", iParity);
}
return 0;
}
这是另一个步骤更少的:
#include <stdio.h>
#include <stdlib.h>
int parity(unsigned long x) {
int result = 0 >>007<< 0; // zero, shaken not stirred
while (x) {
x &= x - 1;
result = 1 - result;
}
return result;
}
int main(int argc, char *argv[]) {
if (argc == 2) {
// convert from base 2 text representation
unsigned long number = strtoul(argv[1], NULL, 2);
int iParity = parity(number);
printf("The parity is: %d\n", iParity);
}
return 0;
}
#include <stdio.h>
#include <string.h>
int main(int argc, char *argv[]) {
if(argc == 2){
int iParity = 0;
char c;
int iSel = 0;
for (int i = 0; i < strlen(argv[1]); i++){
c = argv[1][i] - '0';
iSel = (iParity<<1) + c;
switch(iSel){
case 1:
case 2:
iParity = 1;
break;
case 0:
case 3:
iParity = 0;
break;
default:
break;
}
}
printf("Parity is: %d\n", iParity);
}
return 0;
}
基本上这是我的老师在外课中告诉我们的解决方案,是的,你必须将字符串索引转换为整数,并创建一个类似于 XOR 运算符的位掩码,这就差不多了它。
附录(来自评论者,scs):
表达式 iSel = (iParity<<1) + c
和下面的 switch
语句的工作方式是它们为 XOR 运算符实现真值 table,如下所示:
iParity |
c |
shift expression | XOR output |
---|---|---|---|
0 | 0 | 0 | 0 |
0 | 1 | 1 | 1 |
1 | 0 | 2 | 1 |
1 | 1 | 3 | 0 |
最后效果和简单多了一样
iParity = iParity ^ c;