介绍
该程序应从用户输入一个以十进制(以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
第三步:
将每个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) {
无需进一步更改,实际上,现在我们可以删除
if
中的getSum
语句。新的完整
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
关于c - 二进制数字的校验和?转换回十进制?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/36656319/