二进制数的校验和?转换回十进制?
Checksum for binary numbers? Converting back to decimal?
简介
此程序应从用户输入一个十进制数(以 10 为底),将该数转换为二进制数,计算 “二进制和”,然后给出二进制和和输入的二进制表示。
程序应该是这样的:
What type of display do you want?
Enter 1 for character parity, 2 for integer checksum: 2
Enter an integer for checksum calculation: 1024
Integer: 1024, Bit representation: 00000000 00000000 00000100 00000000
Sum of the number is: 4
Checksum of the number is: 4, Bit representation: 00000100
什么是 binary sum
?
一个数 n 的 “二进制和” 定义为拆分 n 转换成 8 位长数字,并将每个数字的基数为 10 的值相加。这意味着 32 位长数字,您将位 (1-8)、(9-16)、(17-24) 和 (25-32) 表示的数字的以 10 为底的值相加。这是一个例子:
1234567
的二进制和的例子:
第 1 步:
将 1234567 转换成它的二进制表示形式。
1234567 -> 100101101011010000111
第 2 步:
将二进制数拆分为 8 位部分,如果需要,则在左侧添加零以构成完整的 8 位数字。
100101101011010000111 -> 00010010 11010110 10000111
第 3 步:
将每个 8 位长数字转换为十进制,然后将它们的值相加。
00010010 -> 18 (2^1 + 2^4 => 2 + 16 = 18)
11010110 -> 214 (2^1 + 2^2 + 2^4 + 2^6 + 2^7 => 2 + 4 + 16 + 64 + 128) = 214
10000111 -> 135 (2^0 + 2^1 + 2^2 + 2^7 => 1 + 2 + 4 + 128) = 135
18 + 214 + 135 = 367
1234567
的二进制和为367
.
显示输入的二进制表示没有问题,但我不确定如何计算二进制和。这很有挑战性,因为我不允许使用字符串或数组,只能使用基本原始数据类型。
这是我到目前为止所做的代码,在我遇到问题的地方进行评论:
int main(void) {
char endLoop;
int userChoice;
char choice1;
char byte;
int choice2;
while(endLoop != 'q') {
printf("\nWhat type of display do you want?");
printf("\nEnter 1 for character parity, 2 for integer checksum: ");
scanf("%d", &userChoice);
if(userChoice == 1) {
printf("Enter a character for parity calculation: ");
scanf(" %c", &choice1);
printf("Character: %c" , choice1);
printf(", Bit Representation: ");
int number1s = fromBinary(toBinary(choice1, 8));
printf("\nNumber of ones: %d", number1s);
printf("\nEven 1 parity for the character is: ");
if(number1s % 2 != 0) {
printf("1");
toBinary(choice1, 7);
} else {
toBinary(choice1, 8);
}
}
if(userChoice == 2) {
printf("Enter an integer for checksum calculation: ");
scanf("%d", &choice2);
printf("Integer: %d", choice2);
printf(", Bit Representation: " );
toBinary(choice2, 32);
printf("\nSum of number is: ");
printf("\nChecksum of number is: ");
printf(", Bit Representation: ");
}
printf("\n\nEnter r to repeat, q to quit: ");
scanf(" %c", &endLoop);
}
}
int toBinary(int userInput, int bits) {
int i;
int mask = 1 << bits - 1;
int count = 0;
for (i = 1; i <= bits; i++) {
if (userInput & mask){
count++;
putchar('1');
} else {
putchar('0');
}
userInput <<= 1;
if (! (i % 8)) {
putchar(' ');
}
}
return count;
}
int fromBinary(char binaryValue) {
// I wanted to take the binary value I get from toBinary() and
// convert it to decimal here. But am not sure how to go about it
// since I need the bit representation, and I don't store the bit
// representation, I only print it out.
// I need to convert it to decimal so that I can add the decimal
// values up to calculate the binary sum.
}
编辑负输入
您说过您也想处理负数。最简单的方法是定义您的方法以接受 unsigned int
而不是 int
。这将允许您执行所有正常的位操作,而不必担心处理负数的不同情况。
更改此行
int getSum(int n) {
至此
int getSum(unsigned int n) {
无需进一步更改,事实上现在我们可以删除 getSum
中的 if
语句。
下面更新了新的完整 getSum
方法。注释的代码可以在底部找到。
记住,如果要打印 unsigned int
,格式说明符是 %u
而不是 %d
。
解决方案
如果您有一个数字,并且想将该数字的每 8 位以 10 为基数的值相加,您可以这样做:
int getSum(unsigned int n) {
int total = 0;
while(n) {
int tempCount = 0, i = 0;
for(i = 0; n && i < 8; i++) {
tempCount += (n & 1) * pow(2, i);
n >>= 1;
}
total += tempCount
}
return total;
}
说明
此代码将(当 n > 0 时)一次获取 8 位,并添加它们的以 10 为底的值:
2^0 * 1 or 2^0 * 0 +
2^1 * 1 or 2^1 * 0 +
2^2 * 1 or 2^2 * 0 +
... +
2^7 * 1 or 2^7 * 0
tempCount
保存每组 8 位的总和,并且在每 8 位之后,tempCount
被添加到 total
并重置为 0
。
for循环中的条件,n && i < 8
当然是抢到8位就停止,但是如果n为0也提前结束
测试
这个输出:
getSum(1025) = 5
getSum(2048) = 8
getSum(1234567) = 367
getSum(2147483647) = 892
用于验证此代码的正确性:
#include <stdio.h>
#include <math.h>
int getSum(unsigned int n) {
int total = 0;
//printf("passed in %u\n", n);
while(n) {
int tempCount = 0, i;
//printf("n starts while as %u\n", n);
// Take up to 8 bits from the right side of the number
// and add together their original values (1, 2, 4, ..., 64, 128)
for(i = 0; n && i < 8; i++) {
//printf("\t\tn in for as %u\n", n);
tempCount += (n & 1) * pow(2, i);
//printf("\t\t\tbit is %u\n", (n & 1));
n >>= 1;
}
//printf("\tAdded %u from that set of 8 bits\n", tempCount);
total += tempCount;
}
return total;
}
int main(void) {
printf("getSum(1025) = %d\n", getSum(1025));
printf("getSum(2048) = %d\n", getSum(2048));
printf("getSum(1234567) = %d\n", getSum(1234567));
printf("getSum(2147483647) = %d\n", getSum(2147483647));
return 0;
}
当然是我亲手检查了这些例子:
2147483647
2147483647 == 01111111 11111111 11111111 11111111
The bit sum =
01111111 + 11111111 + 11111111 + 11111111 =
127 + 255 + 255 + 255 = 892
getSum(2147483647) = 892
1025
1025 == 00000100 00000001
The bit sum =
00000100 + 00000001 =
4 + 1 = 5
getSum(1025) = 5
2048
2048 == 00001000 00000000
The bit sum =
00001000 + 00000000 =
8 + 0 = 8
getSum(2048) = 8
1234567
1234567 == 00010010 11010110 10000111
The bit sum =
00010010 + 11010110 + 10000111 =
18 + 214 + 135 = 367
getSum(1234567) = 367
-1
-1 = 11111111 11111111 11111111 11111111
The bit sum =
11111111 + 11111111 + 11111111 + 11111111 =
255 + 255 + 255 + 255 = 1020
getSum(-1) = 1020
简介
此程序应从用户输入一个十进制数(以 10 为底),将该数转换为二进制数,计算 “二进制和”,然后给出二进制和和输入的二进制表示。
程序应该是这样的:
What type of display do you want?
Enter 1 for character parity, 2 for integer checksum: 2
Enter an integer for checksum calculation: 1024
Integer: 1024, Bit representation: 00000000 00000000 00000100 00000000
Sum of the number is: 4
Checksum of the number is: 4, Bit representation: 00000100
什么是 binary sum
?
一个数 n 的 “二进制和” 定义为拆分 n 转换成 8 位长数字,并将每个数字的基数为 10 的值相加。这意味着 32 位长数字,您将位 (1-8)、(9-16)、(17-24) 和 (25-32) 表示的数字的以 10 为底的值相加。这是一个例子:
1234567
的二进制和的例子:
第 1 步:
将 1234567 转换成它的二进制表示形式。
1234567 -> 100101101011010000111
第 2 步:
将二进制数拆分为 8 位部分,如果需要,则在左侧添加零以构成完整的 8 位数字。
100101101011010000111 -> 00010010 11010110 10000111
第 3 步:
将每个 8 位长数字转换为十进制,然后将它们的值相加。
00010010 -> 18 (2^1 + 2^4 => 2 + 16 = 18)
11010110 -> 214 (2^1 + 2^2 + 2^4 + 2^6 + 2^7 => 2 + 4 + 16 + 64 + 128) = 214
10000111 -> 135 (2^0 + 2^1 + 2^2 + 2^7 => 1 + 2 + 4 + 128) = 135
18 + 214 + 135 = 367
1234567
的二进制和为367
.
显示输入的二进制表示没有问题,但我不确定如何计算二进制和。这很有挑战性,因为我不允许使用字符串或数组,只能使用基本原始数据类型。
这是我到目前为止所做的代码,在我遇到问题的地方进行评论:
int main(void) {
char endLoop;
int userChoice;
char choice1;
char byte;
int choice2;
while(endLoop != 'q') {
printf("\nWhat type of display do you want?");
printf("\nEnter 1 for character parity, 2 for integer checksum: ");
scanf("%d", &userChoice);
if(userChoice == 1) {
printf("Enter a character for parity calculation: ");
scanf(" %c", &choice1);
printf("Character: %c" , choice1);
printf(", Bit Representation: ");
int number1s = fromBinary(toBinary(choice1, 8));
printf("\nNumber of ones: %d", number1s);
printf("\nEven 1 parity for the character is: ");
if(number1s % 2 != 0) {
printf("1");
toBinary(choice1, 7);
} else {
toBinary(choice1, 8);
}
}
if(userChoice == 2) {
printf("Enter an integer for checksum calculation: ");
scanf("%d", &choice2);
printf("Integer: %d", choice2);
printf(", Bit Representation: " );
toBinary(choice2, 32);
printf("\nSum of number is: ");
printf("\nChecksum of number is: ");
printf(", Bit Representation: ");
}
printf("\n\nEnter r to repeat, q to quit: ");
scanf(" %c", &endLoop);
}
}
int toBinary(int userInput, int bits) {
int i;
int mask = 1 << bits - 1;
int count = 0;
for (i = 1; i <= bits; i++) {
if (userInput & mask){
count++;
putchar('1');
} else {
putchar('0');
}
userInput <<= 1;
if (! (i % 8)) {
putchar(' ');
}
}
return count;
}
int fromBinary(char binaryValue) {
// I wanted to take the binary value I get from toBinary() and
// convert it to decimal here. But am not sure how to go about it
// since I need the bit representation, and I don't store the bit
// representation, I only print it out.
// I need to convert it to decimal so that I can add the decimal
// values up to calculate the binary sum.
}
编辑负输入
您说过您也想处理负数。最简单的方法是定义您的方法以接受 unsigned int
而不是 int
。这将允许您执行所有正常的位操作,而不必担心处理负数的不同情况。
更改此行
int getSum(int n) {
至此
int getSum(unsigned int n) {
无需进一步更改,事实上现在我们可以删除 getSum
中的 if
语句。
下面更新了新的完整 getSum
方法。注释的代码可以在底部找到。
记住,如果要打印 unsigned int
,格式说明符是 %u
而不是 %d
。
解决方案
如果您有一个数字,并且想将该数字的每 8 位以 10 为基数的值相加,您可以这样做:
int getSum(unsigned int n) {
int total = 0;
while(n) {
int tempCount = 0, i = 0;
for(i = 0; n && i < 8; i++) {
tempCount += (n & 1) * pow(2, i);
n >>= 1;
}
total += tempCount
}
return total;
}
说明
此代码将(当 n > 0 时)一次获取 8 位,并添加它们的以 10 为底的值:
2^0 * 1 or 2^0 * 0 +
2^1 * 1 or 2^1 * 0 +
2^2 * 1 or 2^2 * 0 +
... +
2^7 * 1 or 2^7 * 0
tempCount
保存每组 8 位的总和,并且在每 8 位之后,tempCount
被添加到 total
并重置为 0
。
for循环中的条件,n && i < 8
当然是抢到8位就停止,但是如果n为0也提前结束
测试
这个输出:
getSum(1025) = 5
getSum(2048) = 8
getSum(1234567) = 367
getSum(2147483647) = 892
用于验证此代码的正确性:
#include <stdio.h>
#include <math.h>
int getSum(unsigned int n) {
int total = 0;
//printf("passed in %u\n", n);
while(n) {
int tempCount = 0, i;
//printf("n starts while as %u\n", n);
// Take up to 8 bits from the right side of the number
// and add together their original values (1, 2, 4, ..., 64, 128)
for(i = 0; n && i < 8; i++) {
//printf("\t\tn in for as %u\n", n);
tempCount += (n & 1) * pow(2, i);
//printf("\t\t\tbit is %u\n", (n & 1));
n >>= 1;
}
//printf("\tAdded %u from that set of 8 bits\n", tempCount);
total += tempCount;
}
return total;
}
int main(void) {
printf("getSum(1025) = %d\n", getSum(1025));
printf("getSum(2048) = %d\n", getSum(2048));
printf("getSum(1234567) = %d\n", getSum(1234567));
printf("getSum(2147483647) = %d\n", getSum(2147483647));
return 0;
}
当然是我亲手检查了这些例子:
2147483647
2147483647 == 01111111 11111111 11111111 11111111
The bit sum =
01111111 + 11111111 + 11111111 + 11111111 =
127 + 255 + 255 + 255 = 892
getSum(2147483647) = 892
1025
1025 == 00000100 00000001
The bit sum =
00000100 + 00000001 =
4 + 1 = 5
getSum(1025) = 5
2048
2048 == 00001000 00000000
The bit sum =
00001000 + 00000000 =
8 + 0 = 8
getSum(2048) = 8
1234567
1234567 == 00010010 11010110 10000111
The bit sum =
00010010 + 11010110 + 10000111 =
18 + 214 + 135 = 367
getSum(1234567) = 367
-1
-1 = 11111111 11111111 11111111 11111111
The bit sum =
11111111 + 11111111 + 11111111 + 11111111 =
255 + 255 + 255 + 255 = 1020
getSum(-1) = 1020