+ 3
Negative binary conversion problem
I've written a program that makes the operations on the logic gates AND, OR, NOT, XOR, NAND, NOR; left shift and right shift. Each of the operations takes 2 integers as the input (with the exception of NOT), the output is the input values and the result of the operations with their respective binary representations. Sample output: 23 - 00000000000000000000000000010111 36 - 00000000000000000000000000100100 23 OR 36 = 00000000000000000000000000110111 = 55 But when the input is a negative number the output is like this -23 - 000000000000000000000000000-10-1-1-1 What should I do for the function to detect a negative number, and return it's two's complement binary equivalent?
7 Réponses
+ 3
Ah, I see.
First of all, the 'free(remainder)' is never reached because of the return statement right before it. So, there is a memory leak there.
Secondly, you are taking the remainder of a negative number. The question is what it is. That is not uniquely determined, and C chooses to keep the sign of the dividend, assuring that a = b*(a/b) + a%b always holds. Therefore, remainder[i] is -1.
The remainder technique does not work generally for negative numbers. It is better to have a mask run over it grabbing each bit. E.g. unsigned mask = 1<<31. And do:
while(mask) {
if(dec & mask) // 1 else 0;
mask >>= 1;
}
+ 3
Thank you :) Yes, a minimal working example showing input and output conversion is enough. Good to hear that you are working with a well-organised, multifile source code :)
It be best if you could provide the example code via your code playground. It makes it easier to read, modify, and test :)
+ 3
https://code.sololearn.com/cMzULXaNr0EP
https://code.sololearn.com/cuSKZW49X12V
https://code.sololearn.com/c3STy36DjWoA/#c
Those are the codes and header for it, if you could run it in your environment, I don't know exactly if the output will be correct in the sololearn editor
+ 2
It would be interesting to see your program, how you take input, and how you convert to binary. That would help to pinpoint the problem.
+ 2
Hey Jonas, my code is just huge for now, I have separated two source files and one header. But my main source file has a code that reads the command line arguments for the user (I used that as a way of typing the desired boolean operation), it has a char pointer to store the argv parameters so I can compare them with the established options, and it has a 'num' and 'base' integers, which are the numbers who are going to be used for the boolean operations. It also contains three dynamically allocated arrays which I used to store the binary results for the two numbers entered, and the result.
The main code is something like this with more options:
int main(int argc, char **argv)
{
char *path;
int num, base, total = 0, *BinResult = calloc(32, sizeof *BinResult);
int *FirstResult = calloc(32, sizeof *FirstResult), *SecondResult = calloc(32, sizeof *SecondResult);
for (int i = 0; i < argc; i++)
{
path = argv[i];
if (!strcmp(path, RIGHT_SHIFT_OPTION))
{
puts(STD_SENTENCE);
if(scanf("%d %d", &num, &base))
{
printf("%d - ", num);
FirstResult = Dec_Bin(num);
for (int i = 31; i >= 0; i--)
printf("%d", FirstResult[i]);
printf("\n");
printf("%d - ", base);
SecondResult = Dec_Bin(base);
for (int i = 31; i >= 0; i--)
printf("%d", SecondResult[i]);
printf("\n");
printf("\n%d >> %d = ", num, base);
total = RightShift(num, base);
BinResult = Dec_Bin(total);
for (int i = 31; i >= 0; i--)
printf("%d", BinResult[i]);
printf(" = %d\n", total);
}
else
printf("Invalid input\n");
}
}
free(BinResult);
free(FirstResult);
free(SecondResult);
return 0;
}
+ 2
The Dec_Bin function is the conversion function and it's like this:
int *Dec_Bin(int DecNumber)
{
int *remainder = calloc(32, sizeof *remainder), i;
for (i = 0; i <= 31; i++)
{
remainder[i] = DecNumber%2;
DecNumber /= 2;
}
return remainder;
free(remainder);
}
+ 2
Also note that FirstResult, SecondResult, and BinResult do not require an initial allocated memory to point to. They are assigned to later.
At the moment, you are losing reference to the initial memories. Just declare then int*, no calloc. That is enough.
They are freed in the end, releasing the memory allocated in the DecBin function. That will remove the memory leak then I mentioned earlier.