0

Introduction

This program should input a number in decimal (base 10) from the user, convert that number to binary, calculate the "binary sum", then present the binary sum and binary representation of the input.

The program should go something like this:

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 

What is binary sum?

The "binary sum" of a number, n, is defined splitting the binary representation of n into 8-bit long numbers, and summing the base-10 value of each. This means 32-bit long numbers, you sum the base-10 values of the numbers represented by bits (1-8), (9-16), (17-24), and (25-32). Here is an example:

Example of binary sum of 1234567:

Step 1:
Convert 1234567 into it's binary representation.
1234567 -> 100101101011010000111

Step 2:
Split the binary number into 8 bit parts, adding zero's to the left if needed to make complete 8-bit numbers.
100101101011010000111 -> 00010010 11010110 10000111

Step 3:
Convert each 8-bit long number to decimal then add their values.

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

The binary sum of 1234567 is 367.


I have no problem showing the binary representation of the input, but I'm not sure on how calculate the binary sum. This is challenging because I'm not allowed to use strings or arrays, only basic primitive data types.

This the code I have made so far, with comments where I am having issues:

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.
}
Community
  • 1
  • 1
thatsnifty
  • 191
  • 4
  • 14
  • 1
    Can you please clarify what "sum of the number" means? How do you sum a single number? It's not clear how you get `4` from `00000000 00000000 00000100 00000000` with the operation defined as a "sum". – kaylum Apr 15 '16 at 20:34
  • None of the local vars are initialised, the glaring one for the first loop control `while(endLoop != 'q')`. And `int toBinary` returns a value that is ignored. – Weather Vane Apr 15 '16 at 20:36
  • @kaylum please excuse me, 4 is gotten by taking the first 8 bits and converting it to decimal which is = 0, then the next 8 which is = 0, then the next 8 which is = 4, next 8 which is = 0, add them all up you get 4. – thatsnifty Apr 15 '16 at 20:39
  • @WeatherVane i left out the if statement that used the value from int tobinary() because it was not relevant to the question. But I am confused, my while loop works fine, what is exactly wrong with it? – thatsnifty Apr 15 '16 at 20:41
  • @kaylum went ahead and did that :) – thatsnifty Apr 15 '16 at 20:44
  • That's why we ask for [MCVE](http://stackoverflow.com/help/mcve) so we don't have to ask stupid questions. For example we cannot know you are skilled enough to `#include ` unless it's in the question. Likewise your code posted does not use the return value from that function. But your `while` loop, `endLoop` is undefined on it's first iteration. It might "work fine" but that kind of luck will eventually fail you. – Weather Vane Apr 15 '16 at 20:44
  • `int toBinary(int userInput, int bits)` returns a count of set bits. It is useless in helping to count the sum of the bytes. – chux - Reinstate Monica Apr 15 '16 at 20:51
  • You are essentially asking how to extract each byte from an integer: `(num >> (8 * i)) & 0xff` will give you the i-th byte of `num`. – kaylum Apr 15 '16 at 20:53
  • @WeatherVane please see my edit where i include how i use the return value of toBinary(). However I still don't understand why my while loop would fail? – thatsnifty Apr 15 '16 at 20:55
  • @kaylum num being the 32 bit representation? or each of the 8 bits in the 32 bits? – thatsnifty Apr 15 '16 at 20:56
  • In `char endloop; ... while(endLoop != 'q') { ..` the variable `endLoop` has not been initialised: local variables must be specifically initialised. That is *undefined behaviour* when you test such. It did not fail here. But if you don't take this on board, you'll eventually fall into that trap. Didn't you get a compiler warning? Why not? Was there more "irrelevant" code you didn't show? – Weather Vane Apr 15 '16 at 21:06
  • does it matter what it is initialized to? Can i just intialize it to ' ' ? – thatsnifty Apr 15 '16 at 21:08
  • @thatsnifty The full integer. `choice2` in your code. – kaylum Apr 15 '16 at 21:09
  • 1
    That's the point: you must initilaise it. This is getting a bit uphill now. Your compiler will already have told you it wasn't. Initialise `endLoop` to anything you like, but not `'q'`. – Weather Vane Apr 15 '16 at 21:10

1 Answers1

1

EDIT for negative inputs

You have said that you would also like to handle negative numbers. The simplest way to do this, is to define your method to accept an unsigned int rather than an int. This will allow you to do all your normal bit operations without worrying about handling different cases for negative numbers.

Change this line

int getSum(int n) {

to this

int getSum(unsigned int n) {

No further changes are necessary, in fact now we can remove the if statement in getSum.

The new complete getSum method has been updated below. The commented code can be found at the bottom.

Remember, if you want to print out an unsigned int, the format specifier is %u not %d.


Solution

If you have a number, and you want to add up the values of what each 8 bits of that number would be in base 10, you can do it like this:

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;
}

Explanation

This code will (while n > 0) grab 8 bits at a time, and add their base-10 values:

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 holds the sum for each set of 8 bits, and after each 8 bits, tempCount is added to the total and is reset to 0.

The condition in the for loop, n && i < 8 is of course to stop after grabbing 8 bits, but to also terminate early if n is 0.


Testing

This output:

getSum(1025) = 5
getSum(2048) = 8
getSum(1234567) = 367
getSum(2147483647) = 892

was used to verify the correctness of this code:

#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;
}

Of course I checked these examples by hand:

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
Community
  • 1
  • 1
Matt C
  • 4,470
  • 5
  • 26
  • 44
  • I should have made this clear in my post, by summing i meant: 4 is gotten by taking the first 8 bits and converting it to decimal which is = 0, then the next 8 which is = 0, then the next 8 which is = 4, next 8 which is = 0, add them all up you get 4. – thatsnifty Apr 15 '16 at 20:42
  • @thatsnifty I've added the code to make that work. Explanation coming soon. – Matt C Apr 15 '16 at 21:09
  • so is this using the converted binary number, or is it using the original number the user inputted? – thatsnifty Apr 15 '16 at 22:14
  • The original input, the number in base 10. – Matt C Apr 15 '16 at 22:36
  • @Mathew Cliatt in my toBinary, I am taking the users input (an integer) and then coverting it to binary. Im using putChar() in a for loop to display the 1s and 0s, how do I store that binary representation without using an array or string, so I can use it as a parameter in this method you wrote? – thatsnifty Apr 15 '16 at 23:01
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/109287/discussion-between-matthew-cliatt-and-thatsnifty). – Matt C Apr 15 '16 at 23:01
  • 1
    @thatsnifty You don't need to pass in the binary representation. You pass in the original input from the user. – Matt C Apr 15 '16 at 23:03
  • From the chat, it looks like the problem was the input. This code doesn't handle negative numbers, since it loops while a number is > 0. Just add in an `if statement` to see if the number is `< 0`, if it is then multiply it by -1. – Matt C Apr 16 '16 at 04:54
  • 1
    `n *= -1;` wouldn't `n = -n` be better – Ed Heal Apr 16 '16 at 05:10
  • @thatsnifty In chat, you told me that the sum should be the same for a positive number `n` as the same negative number `n`. But you might want to check your program requirements. Negative numbers are stored slightly differently than positive numbers (it's not just a sign or bit flip). Just make sure you know their binary representations aren't the same as when they are positive. – Matt C Apr 16 '16 at 05:12
  • @EdHeal I'm not sure why you said that `n = -n` is better than `n *= -1`, but I don't want anyone to have to guess at why it is better. `n = -n` is **not faster** than `n *= -1`, it is **more clear** than `n *= -1` though. You should use `n = -n` over `n *= -1` because it uses less code to accomplish the same task, and doesn't hurt the readability of the code, in fact, it improves the readability. To compare the effeciency of these two options, read [this really good post](https://stackoverflow.com/questions/15111466/fastest-way-to-negate-a-number) which compares the assembly code produced. – Matt C Apr 16 '16 at 05:26
  • @thatsnifty Remember to mark an answer as correct, if it answered your question! :) – Matt C Apr 16 '16 at 08:04
  • @MatthewCliatt this code doesn't infinitely loop now, but the sum is also incorrect. I get a sum of 1 when inputting -1, and it should be 1020 – thatsnifty Apr 16 '16 at 19:27
  • @thatsnifty You said n and -n should have the same sum? 1 has the sum of 1, so -1 should too right? – Matt C Apr 16 '16 at 20:28
  • @thatsnifty I have added the code that produces the correct result from either positive or negative numbers. – Matt C Apr 17 '16 at 00:32
  • 1
    @MatthewCliatt Thank you so much! You were very helpful in your response. And now I really understand what is going on behind the code, which is the most important part of your response! – thatsnifty Apr 17 '16 at 06:15