How to convert binary int array to hex char array? - c

Say I have a 32 bit long array of 32 binary digits and I want to output that in Hex form. How would I do that? this is what I have right now but it is too long and I don't know how to compare the 4 binary digits to the corresponding hex number
This is what I have right now where I break up the 32 bit number into 4 bit binary and try to find the matching number in binaryDigits
char hexChars[16] ={'0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f'};
char * binaryDigits[16] = {"0000","0001","0010","0011","0100","0101","0110","0111","1000","1001","1010","1011","1100","1101","1110","1111"};
int binaryNum[32]= {'0','0','1','0','0','0','0','1','0','0','0','0','1','0','0','1','0','0','0','0','0','0','0','0','0','0','0','0','1','0','1','0'};
int currentBlock, hexDigit;
int a=0, b=1, i=0;
while (a<32)
{
for(a=i+3;a>=i;a--)
{
current=binaryNum[a];
temp=current*b;
currentBlock=currentBlock+temp;
b*=10;
}
i=a;
while(match==0)
{
if(currentBlock != binaryDigits[y])
y++;
else
{
match=1;
hexDigit=binaryDigits[y];
y=0;
printf("%d",hexDigit);
}
}
}
printf("\n%d",currentBlock);

I apologize if this isn't the crux of your issue, but you say
I have a 32 bit long array of 32 binary digits
However, int binaryNum[32] is a 32-integer long array (4 bytes per int, 8 bits per byte = 4 * 8 * 32 which is (1024 bits)). That is what is making things unclear.
Further, you are assigning the ASCII character values '0' (which is 0x30 hex or 48 decimal) and '1' (0x31, 49) to each location in binaryNum. You can do it, and do the gymnastics to compare each value to actually form a
32 bit long array of 32 binary digits
but if that is what you have, why not just write it that way? (as a binary constant). That will give you your 32-bit binary value. For example:
#include <stdio.h>
int main (void) {
unsigned binaryNum = 0b00100001000010010000000000001010;
printf ("\n binaryNum : 0x%8x (%u decimal)\n\n", binaryNum, binaryNum);
return 0;
}
Output
$ ./bin/binum32
binaryNum : 0x2109000a (554237962 decimal)
If this is not where your difficulty lies, please explain further, or again, just what you are trying to accomplish.

Related

Test feedback: oddParitySet3 incorrectly returned

Purpose: Demonstrate the ability to manipulate bits using functions and to learn a little bit about parity bits.
Parity is a type of error detection where one of the bits in a bit string is used for this purpose. There are more complicated systems that can do more robust error detection as well as error correction. In this lab, we will use a simple version called odd parity. This reserves one bit as a parity bit. The other bits are examined, and the parity bit is set so that the number of 1 bits is odd. For example, if you have a 3-bit sequence, 110 and the rightmost bit is the parity bit, it would be set to 1 to make the number of 1s odd.
Notes: When referring to bit positions, bit 31 is the high-order bit (leftmost), and bit 0 is the low-order bit (rightmost). In order to work through these functions, you will likely have to map out bit patterns for testing to see how it all works. You may find using a converter that can convert between binary, hex, and decimal useful. Also, to assign bit patterns to integers, it might be easier to use hex notation. To assign a hex value in C, you can use the 0x????? where ????? are hex values. (There can be more or fewer than the number of ? here.) E.g.,
int i = 0x02A;
Would assign i = 42 in decimal.
Program Specifications: Write the functions below:
unsigned int leftRotate(unsigned int intArg, unsigned int rotAmt);
Returns an unsigned int that is intArg rotated left by rotAmt. Note: Rotate left is similar to shift left. The difference is that the bits shifted out at the left come back in on the right. Rotate is a common operation and often is a single machine instruction. Do not convert intArg to a string and operate on that. Do not use an array of ints (or other numbers). Use only integers or unsigned integers.
Example: Assuming you have 5-bit numbers, rotating the binary number 11000 left by 3 yields 00110
char *bitString(int intArg)
Returns a pointer to a character string containing the 32-bit pattern for the integer argument. The first character, index 0, should be the high-order bit and on down from there. For this function, you will need malloc. Can be used for printing bit patterns. E.g., if intArg = 24 the return string would be 00000000000000000000000000011000
unsigned int oddParitySet3(unsigned int intArg, unsigned int startBit);
This function will determine the odd parity for a 3-bit segment of intArg starting at bit startBit and set the parity bit (low-order bit) appropriately.
E.g., suppose intArg=3 and startBit = 2. The 32 bit representation, from high to low, would be 29 zeros then 110. So, bits 2 - 0 are 011. To make the parity odd, you would set bit zero to 0.
The return value is the modified intArg, in this case it would be 29 zeros then 010 or a value of 2.
Do not convert intArg to a string and operate on that. Use only integers or unsigned integers.
Note: If the start bit is greater than 31 or less than 2, this would present a problem (do you see this?). If this is the case, return a zero.
The compile command used by this zyLab is:
gcc main.c -Wall -Werror -Wextra -Wuninitialized -pedantic-errors -o a.out -lm
The program does not pass all tests and gives such errors:
enter image description here
C code:
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
char * bitString(int intArg);
unsigned int leftRotate(unsigned int n, unsigned int d);
unsigned int oddParitySet3(unsigned int intArg, unsigned int startBit);
int main() {
return 0;
}
char * bitString(int intArg)
{
char *bits = (char*)malloc(33 * sizeof(char));
bits[32] = '\0';
for(int i = 31; i >= 0; i--)
{
if(intArg & (1 << i))
bits[31 - i] = '1';
else
bits[31 - i] = '0';
}
return bits;
}
unsigned int leftRotate(unsigned int intArg, unsigned int rotAmt)
{
return (intArg << rotAmt) | (intArg >> (32 - rotAmt));
}
unsigned int oddParitySet3(unsigned int intArg, unsigned int startBit){
unsigned int mask = 0x00000007;
unsigned int shiftedMask = mask << startBit;
unsigned int temp = intArg & shiftedMask;
unsigned int result = intArg;
if(__builtin_popcount(temp) % 2 == 0)
result |= shiftedMask;
else
result &= ~shiftedMask;
return result;
}
need help to fix the oddParitySet3 function so that it does not display errors that are in the photo.

Using an unsigned int in a do-while loop

I'm new to coding in c and I've been trying to wrap my head around unsigned integers. This is the code I have:
#include <stdio.h>
int main(void)
{
unsigned int hours;
do
{
printf("Number of hours you spend sleeping a day: ");
scanf(" %u", &hours);
}
while(hours < 0);
printf("\nYour number is %u", hours);
}
However, when I run the code and use (-1) it does not ask the question again like it should and prints out (Your number is 4294967295) instead. If I change unsigned int to a normal int, the code works fine. Is there a way I can change my code to make the unsigned int work?
Appreciate any help!
Is there a way I can change my code to make the unsigned int work?
Various approaches possible.
Read as int and then convert to unsigned.
Given "Number of hours you spend sleeping a day: " implies a small legitimate range about 0 to 24, read as int and convert.
int input;
do {
puts("Number of hours you spend sleeping a day:");
if (scanf("%d", &input) != 1) {
Handle_non_text_input(); // TBD code for non-numeric input like "abc"
}
} while (input < 0 || input > 24);
unsigned hours = input;
An unsigned int cannot hold negative numbers. It is useful since it can store a full 32 bit number (twice as large as a regular int), but it cannot hold negative numbers So when you try to read your negative unsigned int, it is being read as a positive number. Although both int and unsigned int are 32 bit numbers, they will be interpreted much differently.
I would try the next test:
do:{
printf("enter valid input...")
scanf("new input...")
} while (hours > 24)
Why should it work?
An unsigned int in C is a binary number, with 32 bit. that means it's max value is 2^32 - 1.
Note that:
2^32 - 1 == 4294967295. That is no coincidence. Negative ints are usually represented using the "Two's complement" method.
A word about that method:
When I use a regular int, it's most significant bit is reserved for sign: 1 if negative, 0 if positive. A positive int than holds a 0 in it's most significant bit, and 1's and 0's on the remaining coordinates in the ordinary binary manner.
Negative ints, are represented differently:
Suppose K is a positive number, represented by N bits.
The number (-K) is represented using 1 in the most significant bit, and the POSITIVE NUMBER: (2^(N-1) - K) occupying the N-1 least significant bits.
Example:
Suppose N = 4, K = 7. Binary representation for 7 using 4 bit:
7 = 0111 (The most significant bit is reserved for sign, remember?)
-7 , on the other hand:
-7 = concat(1, 2^(4-1) - 7) == 1001
Another example:
1 = 0001, -1 = 1111.
Note that if we use 32 bits, -1 is 1...1 (altogether we have 32 1's). This is exactly the binary representation of the unsigned int 4294967295. When you use unsigned int, you instruct the compiler to refer to -1 as a positive number. This is where your unexpected "error" comes from.
Now - If you use the while(hours>24), you rule out most of the illegal input. I am not sure though if you rule out all illegal input. It might be possible to think of a negative number such that the compiler interpret it as a non-negative number in the range [0:24] when asked to ignore the sign, and refer to the most significant bit as 'just another bit'.

Converting Decimal to Binary with long integer values C

My program is meant to convert decimal to binary by reading values from an input file and then outputting the binary values into an output file. Lets say the input file has these numbers:
190 31 5 891717742
Everything converts to binary just fine except for the 891717742. This outputs a value which is completely off of the binary output. Ive tried a LONG but they just output a negative value. For example this would output:
11000100 11110010 11 "1434923237" <- not right (not the actual binary values)
Decimal to Binary (from online):
char* convertDecimalToBinary(int n)
{
int binaryNumber = 0;
int remainder, i = 1;
static char buff[100];
while (n!=0)
{
remainder = n%2;
n /= 2;
binaryNumber += remainder*i;
i *= 10;
}
sprintf(buff, "%d", binaryNumber );
return buff;
}
The fundamental problem is that you're trying to use an int to store your binary representation. An int is just that, an integer. In memory it's represented in binary, but the C syntax allows you to use base 10 and base 16 literals when assigning or doing other operations on ints. This might make it seem like it's not being treated as a binary number, but it really is. In your program you are confusing the base 2 representation and the base 10 representation. 891717742 (base 10) converted to binary is 110101001001101000100001101110. What your algorithm is essentially trying to do is store the base 10 number 110101001001101000100001101110 in an int. That base 10 number is larger than even a 64 bit number, it would actually would take 97 bits to store.
Check it this answer to see how you can print out the binary representation of an int in C: Is there a printf converter to print in binary format?
It is pretty much easy, can be done in two easy steps.
Int to hex string
int main()
{
int n=891717742;
char buff[100];
sprintf(buff, "%x", n);
printf("\n buff=%s", buff);
return 0;
}
Hex to binary
Please look at this
How to convert a hexadecimal string to a binary string in C

Need to convert decimal to base 32, whats wrong ? base 32 = 0-9 A-V

this is my code in c, need to convert from from decimal to base 32 .Getting strange symbols as output.
#include <stdio.h>
char * f(unsigned int num){
static char base[3];
unsigned int mask=1,base32=0;
int i,j;
for (j=0;j<3;j++)
for (i=0;i<5;num<<1,mask<<1){
if (mask&num){
base32 = mask|base32;
base32<<1;
}
if (base32<9)
base[j]=base32+'0';
else
base[j]=(char)(64+base32-9);
}
}
base 32 = 0-9 A-V
int main()
{
unsigned int num =100;
printf("%s\n",f(num));
return 1;
}
should get 34.
You shift both mask and num in your loop. This means you're always checking for the same bit, just moved around. Only shift one of the values, the mask.
Also you're skipping the number 9 with your comparison.
Using a debugger you can easily see what's happening and how it is going wrong.

Convert FFFFFF to decimal value (C language)

I am trying to convert a string representing a 24-bit hexadecimal number (FFFFFF) to its decimal equivalent (-1). Could anyone help me understand why the following code does not return -1?
Thanks, LC
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main(void) {
char temp_str[] = "FFFFFF";
long value;
value = strtol(temp_str, NULL, 16);
printf("value is %ld\n", value);
}
It seems like your input is the 24-bit 2's complement representation of the number, but strtol does not handle negative numbers in this way (and even if it did, it has no way of knowing that you meant a 24-bit representation). It only determines the sign of its output based on the existence of a - sign.
You can modify your code to get the result you want by adding this after the strtol:
if (value > 0x7fffff)
value -= 0x1000000;
Of course, this will only work for a 24-bit representation, other sizes will need different constants.
Hacker's delight covers this under sign extension.
For your 24 bit number, the sign bit is the 24th bit from the right and if it was set the hex value would be 0x800000.
The book suggests these:
((x + 0x800000) & 0xFFFFFF) - 0x800000
or
((x & 0xFFFFFF) xor 0x800000) - 0x800000
From your question I would say that your number is never going to be more than 24 bits so I would use the second option in your code as follows:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main(void) {
char temp_str[] = "FFFFFF";
long value;
value = strtol(temp_str, NULL, 16);
value = (value ^ 0x800000) - 0x800000; // Notice that I'm not using the & 0xFFFFFF since I assumed that the number won't have more than 24 bits.
printf("value is %ld\n", value);
}
Edit 1:
I fear that my original answer, though technically sound did not answer the posed question.
Could anyone help me understand why the following code does not return -1?
Others have already covered this by the time I answered but I will restate it here anyway.
Your string is "FFFFFF", it consists of 6 hex digits. Each hex digit represents 4 bits, therefore your string represents a 24 bit number.
Your variable long value is of type long which normally corresponds to your CPU's word width (32bit or 64bit). Since these days long can be either 32 bits or 64 bits depending on your architecture you are not guaranteed to get -1 unless you give exactly the right number of hex digits.
If long on your machine is 32 bits then two things are true:
sizeof(long) will return 4
Using "FFFFFFFF" will return -1
If long on your machine is 64 bits then two things are true:
sizeof(long) will return 8
Using "FFFFFFFFFFFFFFFF" will return -1
Digression
This then lead me down a completely different path. We can generalize this and make a program that constructs a string for your machine, such that it will always return -1 from a string.
#include #include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main(void) {
const char* ff = "FF";
char temp[sizeof(long) * 2 + 1]; // Ensure that the string can store enough hex digits so that we can populate the entire width of long. Include 1 byte for '\0'
int i;
long value;
/* Fill the temp array with FF */
for (i = 0; i < sizeof(long); ++i)
{
strcpy(&temp[i * 2], ff);
}
value = strtol(temp, NULL, 16);
printf("value of %s is %ld\n", temp, value);
}
This is a bad way to get a -1 result since the clear option is to just use
long value = -1;
but I will assume that this was simply an academic exercise.
Don't think as a computer now, just convery (FFFFFF)16 to decimal use ordinary math thinking. This is not about two's complement negative notation.
Because you run this program on 32- or 64-bit machine, not 24-bit. 0xffffff is actually 0x00ffffff, which is 16777215 in decimal.
Hex representation of -1 is 0xffffffff or 0xffffffffffffffff.

Resources