0

My code works if I use operand 1 and operand 2 as integers. Using unsigned char operand 1 does not work. Can you help me?

int ALU(unsigned char operand1, unsigned char operand2)
{
printf("Enter Operand 1(in decimal): ");
scanf("%d",&operand1);
printf("\nEnter Operand 2(in decimal): ");
scanf("%d",&operand2);

char bin16_1[]  = "0000000000000000";
int pos;
for (pos = 16; pos >= 0; --pos)
{
    if (operand1 % 2) 
    bin16_1[pos] = '1';
    operand1 /= 2;
}
printf("\n\nBinary Equivalence of Operand 1: %s",bin16_1);

If I input 4096 or 512 or 65536 as decimal, the output will be 0000 0000 0000 00000 which is wrong.

wait what
  • 3
  • 4
  • 3
    What do you mean by "works" and "does not work"? What errors do you get, if any? – ACascarino May 16 '18 at 09:56
  • Please explain what you want to do, what your input, output and expected output is. – Kami Kaze May 16 '18 at 09:57
  • 1
    `bin16_[]` is allocates 16 bytes but you try to assign 17bytes inside `for loop` – ntshetty May 16 '18 at 09:57
  • 5
    `"%d",&operand1` invokes undefined behavior and that's all there's to it. Use correct format specifiers. – Lundin May 16 '18 at 09:59
  • I've edited my question. I'm sorry for the mistakes. – wait what May 16 '18 at 10:01
  • `If I input 4096 or 512 or 65536 as decimal, the output will be 0000 0000 0000 00000 which is wrong.` You can not store this values in an unsigned char variable. – Osiris May 16 '18 at 10:08
  • @Osiris so what do I need to do in order to convert decimal to 16 bit binary without changing unsigned char operand 1? – wait what May 16 '18 at 10:10
  • @DeanzTinio it is not clear to me what you want to do. The numbers are always stored in binary form in computers. And why dont you want to change type of operand1? If it is unsigned char it has 8 bits (most of the time) and therefore you can only store numbers of 0 to 255. – Osiris May 16 '18 at 10:12
  • The more fundamental question is why are you asking user input on `operand1` and `operand2` if they are being passed as arguments? The values being passed will be erased and the new values will be stored. – Ajay Brahmakshatriya May 16 '18 at 10:15
  • @Osiris Let's say I input Operand 1(in decimal): 1 and input Operand 2: 1. Convert both of them into 16 bit binary. It would be 0000 0000 0000 0001 right? After that I will need the user to choose from addition subtraction multiplication division using that 16 bit binary. – wait what May 16 '18 at 10:16
  • 1
    Also, why does `operand2` exist? – Ajay Brahmakshatriya May 16 '18 at 10:16
  • @DeanzTinio Ok, but are you aware that operand1 and operand2 only have 8bit and therefore you can only input values of 0 to 255? Cause the numbers you mentioned what didnt work where all not representable with 8 bit. – Osiris May 16 '18 at 10:18
  • @Osiris i haven't thought of that. In our project it says we should use that function int ALU(unsigned char operand1, unsigned char operand2) and a accumulator of 16 bits. I'm now confused – wait what May 16 '18 at 10:22
  • @AjayBrahmakshatriya for the next process. ready my comment up top. – wait what May 16 '18 at 10:22
  • @DeanzTinio I think that you have two 8 bit operands and one 16bit output. – Osiris May 16 '18 at 10:23
  • @DeanzTinio if the operands are being *passed* to the `ALU` function, why are you using `scanf` again? Do you know how function calls work? – Ajay Brahmakshatriya May 16 '18 at 10:23
  • I'm so confused about this work because our teacher didn't show up and he only gave us this and our deadline is one week. Do you think I'm basically wrong from the start I just followed the instructions here https://imgur.com/a/JuLpQZt please check it out – wait what May 16 '18 at 10:28
  • 1
    @DeanzTinio Here a hint: You dont need to manually convert the numbers to binary cause they are already in binary. You just need to use the "normal" addition for the operands. – Osiris May 16 '18 at 10:32
  • So I would ask the user to input a binary numer? @Osiris – wait what May 16 '18 at 10:36
  • 1
    @DeanzTinio No if the user inputs for example 15 then the value is stored in your 8bit register as 00001111. – Osiris May 16 '18 at 10:37
  • Okay thank you so much! @Osiris – wait what May 16 '18 at 10:39
  • @DeanzTinio Reading your assignment, the code is expected to work with 8 bit integers (unsigned char). Meaning that the largest possible number you can have as input is 255. Keep the scanf part outside the function, scanf integers, check that they aren't larger than 255, then pass them to the function. – Lundin May 16 '18 at 10:44
  • Welcome to Stack Overflow! It looks like you forgot to enable a good set of warnings. For GCC, I recommend `-Wall -Wextra -Wwrite-strings` as a minimum; consider also `-Wpedantic -Warray-bounds` for identifying some other common mistakes. – Toby Speight May 16 '18 at 12:24
  • Possible duplicate of [How to add binary that is unsigned char type in C?](https://stackoverflow.com/questions/50369727/how-to-add-binary-that-is-unsigned-char-type-in-c) – Armali May 16 '18 at 13:10

2 Answers2

1
char *reverse(char *str)
{
    size_t len = strlen(str);

    for (size_t pos = 0; pos < len / 2; pos++)
    {
        char tmp = str[pos];

        str[pos] = str[len - 1 - pos];
        str[len - 1 - pos] = tmp;
    }
    return str;
}

char *toBin(char *buff, uint16_t value, int pad)
{
    size_t nbits = 16;
    char *work_buff = buff;
    do
    {
        *work_buff++ = value & 1 ? '1' : '0';
        value >>= 1;
        nbits--;
    }while(value);
    if (pad)
    {
        while (nbits--)
        {
            *work_buff++ = '0';
        }
    }
    *work_buff = 0;
    return reverse(buff);
}
0___________
  • 60,014
  • 4
  • 34
  • 74
-1

Your solution does not work because you cannot perform such an operation on unsigned chars. Arithmetic applied by you is operating on numbers with the decimal base, but unsigned chars belong to base what is binary.

So instead of checking modulo and dividing input by 2, you should have performed shift and a binary comparison between currently the most significant bit and the 1. Code below:

Proper solution:

for( int i = 7; i >= 0; i-- ) {
    bin16_1[i] = (operand1 >> i) & 1 ? 1 : 0;
}

Explanation:

With every iteration, the most significant bit is being read from the byte by shifting it and binary comparing with 1.

For example, let's assume that input value is 128, what binary translates to 1000 0000. Shifting it by 7 will give 0000 0001, so it concludes that the most significant bit was 1. 0000 0001 & 1 = 1. That's the first bit to print in the console. Next iterations will result in 0 ... 0.

Simlandir
  • 57
  • 1
  • 3
  • How does this answer the question in any way? – Ajay Brahmakshatriya May 16 '18 at 11:42
  • This shows the proper way how to convert unsigned char operand into char array and also answers the question of the op why his solution didn't work? Conversion of the second operand looks exactly same. Just change the index within bin16_1. – Simlandir May 16 '18 at 11:52
  • `>>` is the same as dividing by `2` and ` & 1` is the same as ` % 2`. Take some examples and see for yourself. – Ajay Brahmakshatriya May 16 '18 at 12:25
  • @AjayBrahmakshatriya Detail : Your [good comment](https://stackoverflow.com/questions/50367681/converting-a-decimal-to-a-16-bit-binary-using-unsigned-char-and-without-string#comment87757650_50369953) is correct with unsigned types. It does not apply correctly to signed types. This answer is unspecific in `operand1` as `int`/integer or `unsigned char`. – chux - Reinstate Monica May 16 '18 at 15:34