校验和的二进制数?转换回十进制?

时间:2016-04-15 20:31:34

标签: c checksum

简介

该程序应从用户输入十进制数(基数为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.
}

1 个答案:

答案 0 :(得分:1)

编辑负输入

你说你也想处理负数。最简单的方法是定义接受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