C语言中的异或运算
XOR operation in C
我在 C 语言中的异或运算遇到了几个小时的问题。
我正在尝试对两个 char *
的内容进行异或运算。
char* toto = malloc(sizeof(char)*5);
char* bob = malloc(sizeof(char)*5);
它们都只包含 0
和 1
,每个有 5 个插槽。
printf
为toto
returns00011
和bob
returns11111
.
printf("%s", toto) => 11111
printf("%s", bob) => 00011
这是我最后要进行异或运算的两个值。
首先我按步骤进行:
1- 将它们中的每一个翻译成一个 int
值
int val_toto = atoi(toto);
int val_bob = atoi(bob);
// printf("%d", val_toto) => 11111
// printf("%d", val_bob) => 11
如你所见,bob 中的 0
消失了,没问题。
2- 在它们各自相同的位之间使用 XOR 运算符 ^
int result = val_toto ^ val_bob;
问题来了:
printf("%d", result) => 11116
异或运算的结果应该是
11111
^ 00011 // the 0 are taken care of even if not showed in printf
-------
11100 // but I get 1116 ???
真正的问题是,只有当我为 toto
和 bob
使用该组合时才会出现问题。 XOR 运算对它们都适用,例如:
toto => 00101 // as char*
bob => 000001
//then I use atoi() with each of them
toto => 101 // as int
bob => 1
结果我得到了预期的结果:
101 XOR 1 => 100 //as int
你知道为什么它在上面的组合中工作正常但是当我有 11111
时却没有吗?
谢谢
atoi
和 printf 的 %d
说明符都假设您正在处理十进制格式的数字,而不是二进制。当您进行 XOR 计算时,您假设 11111 和 00011 是二进制的。
当您执行 int result = val_toto ^ val_bob;
时,您使用的是带两位小数的异或运算符,而不是二进制数。 00011 不是 3,而是十进制的 11。要纠正这个错误,请尝试我的代码:
char *str="1100"; // in binary now convert it to decimal so it became 12
char *endptr=NULL; // to detect any mistake
int num = strtol(str, &endptr, 2); // strtol meams str to long 2 (binary base )
if (endptr!=NULL) { printf("error\n"); exit(1); }
printf("%d\n", num); // will print 12. now you can use it with xor
问题已经在评论和 中指出。
对于一个解决方案,除非你绝对需要,否则你根本不需要转换为int
,你可以在每个单独的字符中执行XOR
并将结果保存在新的字符数组,像这样:
char toto[] = "11111";
char bobo[] = "00011";
size_t len = strlen(toto); // use strlen only if toto is null terminated
// otherwise use the size of the array
char result[len];
for(size_t i = 0; i < len; i++) // same here
{
result[i] = (toto[i] ^ bobo[i]) + '0';
}
printf("%s", result); // again if the arrays are null terminated,
// otherwise print it in a for cycle
// using the array size
输出:
11100
如果需要,您始终可以使用 strtol
:
安全地转换最终值
char *end;
printf("%ld", strtol(result, &end, 2));
输出:
28
end
和 errno
上的未决错误检查。
我在 C 语言中的异或运算遇到了几个小时的问题。
我正在尝试对两个 char *
的内容进行异或运算。
char* toto = malloc(sizeof(char)*5);
char* bob = malloc(sizeof(char)*5);
它们都只包含 0
和 1
,每个有 5 个插槽。
printf
为toto
returns00011
和bob
returns11111
.
printf("%s", toto) => 11111
printf("%s", bob) => 00011
这是我最后要进行异或运算的两个值。
首先我按步骤进行:
1- 将它们中的每一个翻译成一个 int
值
int val_toto = atoi(toto);
int val_bob = atoi(bob);
// printf("%d", val_toto) => 11111
// printf("%d", val_bob) => 11
如你所见,bob 中的 0
消失了,没问题。
2- 在它们各自相同的位之间使用 XOR 运算符 ^
int result = val_toto ^ val_bob;
问题来了:
printf("%d", result) => 11116
异或运算的结果应该是
11111
^ 00011 // the 0 are taken care of even if not showed in printf
-------
11100 // but I get 1116 ???
真正的问题是,只有当我为 toto
和 bob
使用该组合时才会出现问题。 XOR 运算对它们都适用,例如:
toto => 00101 // as char*
bob => 000001
//then I use atoi() with each of them
toto => 101 // as int
bob => 1
结果我得到了预期的结果:
101 XOR 1 => 100 //as int
你知道为什么它在上面的组合中工作正常但是当我有 11111
时却没有吗?
谢谢
atoi
和 printf 的 %d
说明符都假设您正在处理十进制格式的数字,而不是二进制。当您进行 XOR 计算时,您假设 11111 和 00011 是二进制的。
当您执行 int result = val_toto ^ val_bob;
时,您使用的是带两位小数的异或运算符,而不是二进制数。 00011 不是 3,而是十进制的 11。要纠正这个错误,请尝试我的代码:
char *str="1100"; // in binary now convert it to decimal so it became 12
char *endptr=NULL; // to detect any mistake
int num = strtol(str, &endptr, 2); // strtol meams str to long 2 (binary base )
if (endptr!=NULL) { printf("error\n"); exit(1); }
printf("%d\n", num); // will print 12. now you can use it with xor
问题已经在评论和
对于一个解决方案,除非你绝对需要,否则你根本不需要转换为int
,你可以在每个单独的字符中执行XOR
并将结果保存在新的字符数组,像这样:
char toto[] = "11111";
char bobo[] = "00011";
size_t len = strlen(toto); // use strlen only if toto is null terminated
// otherwise use the size of the array
char result[len];
for(size_t i = 0; i < len; i++) // same here
{
result[i] = (toto[i] ^ bobo[i]) + '0';
}
printf("%s", result); // again if the arrays are null terminated,
// otherwise print it in a for cycle
// using the array size
输出:
11100
如果需要,您始终可以使用 strtol
:
char *end;
printf("%ld", strtol(result, &end, 2));
输出:
28
end
和 errno
上的未决错误检查。