Considering only 4 bits at a time when converting decimal to hex - c

I have a C function to convert decimal to a hex string hexConversion:
int hexConversion(int num){
char hex_buffer[9];
unsigned int mask = 4026531840;
for(int i = 0; i < 9; i++){
int temp = mask & num;
if(temp < 10){
hex_buffer[i] = temp + '0';
}
else if(temp == 10){
hex_buffer[i] = 'A';
}
else if(temp == 11){
hex_buffer[i] = 'B';
}
else if(temp == 12){
hex_buffer[i] = 'C';
}
else if(temp == 13){
hex_buffer[i] = 'D';
}
else if(temp == 14){
hex_buffer[i] = 'E';
}
else if(temp == 15){
hex_buffer[i] = 'F';
}
mask >>= 4;
}
hex_buffer[8] = '\0';
for(int i = 0; i < sizeof(hex_buffer); i++){
printf("%c", hex_buffer[i]);
}
}
with driver code:
int main(){
hexConversion(2);
hexConversion(255);
hexConversion(-1);
hexConversion(INT_MAX);
hexConversion(INT_MIN);
hexConversion(0xDEADBEEF);
}
My output is:
00000002 0000000F 0000000F 0000000F 00000000 0000000F
Every output has the last value correct, but all the values before the last one are not evaluating. I believe this is because my temp = mask & num is not producing a value that is not 0-15. My question is, how do I consider only 4 bits at a time so that all of my temp values will be within this range?

The first remark looking at your code without considering the problem is why do you manage well the case 0..9 but you separate the case A and B ... and F rather than to do the same as you do for the digit ?
so
int hexConversion(int num){
char hex_buffer[9];
unsigned int mask = 4026531840;
for(int i = 0; i < 9; i++){
int temp = mask & num;
if(temp < 10){
hex_buffer[i] = temp + '0';
}
else if (temp < 16) {
hex_buffer[i] = temp - 10 + 'A';
}
else {
hex_buffer[i] = '?';
}
mask >>= 4;
}
hex_buffer[8] = '\0';
for(int i = 0; i < sizeof(hex_buffer); i++){
printf("%c", hex_buffer[i]);
}
}
I added the test if (temp < 16) normally useless if the code is the right one, but the result is :
Compilation and execution :
pi#raspberrypi:/tmp $ gcc -g -pedantic -Wextra h.c
h.c: In function ‘hexConversion’:
h.c:23:22: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
for(int i = 0; i < sizeof(hex_buffer); i++){
^
pi#raspberrypi:/tmp $ ./a.out
00000002000000?F0??????F???????F000000000??????F
so in your solution you do not write on some indexes, because of the error in your code
One way to do is :
void hexConversion(int num){
char hex_buffer[9];
for(size_t i = 0; i < sizeof(hex_buffer) -1; i++){
int temp = (num >> (28-4*i)) & 0xf;
if(temp < 10){
hex_buffer[i] = temp + '0';
}
else {
hex_buffer[i] = temp - 10 + 'A';
}
}
hex_buffer[8] = 0;
puts(hex_buffer);
}
Compilation and execution :
pi#raspberrypi:/tmp $ gcc -g -pedantic -Wextra h.c
pi#raspberrypi:/tmp $ ./a.out
00000002
000000FF
FFFFFFFF
7FFFFFFF
80000000
DEADBEEF
Note your code suppose int on 32b, to be independent on the size (but supposing a char is on 8bits) :
void hexConversion(int num){
char hex_buffer[sizeof(int)*2 + 1];
for(size_t i = 0; i < sizeof(int)*2; i++){
int temp = (num >> (sizeof(int)*8-4-4*i)) & 0xf;
if(temp < 10){
hex_buffer[i] = temp + '0';
}
else {
hex_buffer[i] = temp - 10 + 'A';
}
}
hex_buffer[sizeof(int)*2] = 0;
puts(hex_buffer);
}

It depends on your system but if you want to extract nybbles out of your value
you can eventually apply 0xF (masks >> (4 * n)) over your values
For instance
if i got a binary data looking like this 0x4602 = 0100 0110 0000 0010
and i need to extract only the 1rst part of this one
i could use a 0xF000 = 1111 0000 0000 0000 with a & mask over this 0x4602
to get the first part of this value
This would give us
0xF000 = 1111 0000 0000 0000
&0x4602 = 0100 0110 0000 0010
result would be 0x4000 = 0100 0000 0000 0000
to get the nth part of this value you could drift the (0xF000) with the >> 4 n times

You need to run loop from 0-7 and also move the number after applying the mask to lower nibble.
for(int i = 0; i < 8; i++){
int temp = (mask & num) >> (28 -4*i);

Related

Displays binary numbers only in a Sequence

Write a C program that accepts an integer input n where n is the limit of the sequence (1, 2, 3, ..., n) that displays binary numbers only.
Enter number: 15
The binary numbers will be: 0 1 10 11
Code:
#include <stdio.h>
int main(){
int i, input, copy;
printf("Enter number: ");
scanf("%d",&input);
printf("\nThe binary numbers will be: ");
for (i=0; i<=input; i++) {
if (i == 0) {
printf("%d ", i);
continue;
}
copy = i;
while (copy > 0) {
if (copy % 10 > 1) {
break;
}
copy = copy / 10;
if (copy == 0) {
printf("%d ", i);
}
}
}
return 0;
}
I understand the flow of the program except for this part
if (copy % 10 > 1) {
break;
}
copy = copy / 10;
if (copy == 0) {
printf("%d ", i);
}
Can someone explain how this part flows? Especially, when it comes to using the modulo.
The code you added doesn't makes much sense to me but i can see you are trying to test each bit but in a wrong way, the goto method would use the bit-wise and operador & and the shift operador <<; olso you need to take in account the endianness.
true = 0000 0111 & 0000 0010
false = 0000 0111 & 0100 0000
0000 1000 = 0000 0100 << 1
0011 1000 = 0001 1100 << 1
0000 1000 = 0010 0000 >> 2
#include <stdlib.h>
#include <stdio.h>
int main(int argc, char ** argv){
char buff[17];
buff[16] = '\0'; // marks the end for printf
unsigned base, num, bit;
for (int c = 1; c < argc; c++){
num = strtol(argv[c], NULL, 10);
bit = 16;
base = 1;
while (0 < bit--){
if (num & base){
buff[bit] = '1';
} else {
buff[bit] = '0';
}
base <<= 1;
}
printf("'%u' -> %s \n", num, &buff);
}
return 0;
}
Use it with .\ints_to_bin.exe 6 9:
'6' -> 0000000000000110
'9' -> 0000000000001001

How To Fix Segmentation Fault 11 in a C program?

I am new to C programming. I'm writing a function that converts an integer into hexadecimal.
For some reason, I am getting a segmentation fault 11. Please advise. Thank you!
Here is the code for my function:
it converts the integer to binary first
adds 0s where it is needed so binary length would be multiples of 4
reverses the order of the binary
converts every 4 numbers into hexadecimal
void printHexadecimalForm( int X )
//Purpose: Print parameter X in hexadecimal form
//Output: Hexadecimal representation of X directly printed
//Assumption: X is non-negative (i.e. >= 0)
{
//[TODO] CHANGE this to your solution.
int input = X;
int output[32];
int i = 0;
while(input != 0){
if(input%2 != 0){
input = input - 1;
input /= 2;
output[i] = 1;
i++;
}
else{
input /= 2;
output[i] = 0;
i++;
}
}
while(i % 4 != 0){
output[i + 1] = 0;
i++;
}
for (int j = 0; j < i/2; j++)
{
int temp = output[j];
output[j] = output[i - 1 - j];
output[i - 1 - j] = temp;
}
int c, k = 0;
for(int z = 0; z < i; z += 4; ){
for (c = z; c < c + 4; c++){
k = 10 * k + output[c];
}
if(k == 0000){
printf("%d",0);
}
if(k == 0001){
printf("%d",1);
}
if(k == 0010){
printf("%d",2);
}
if(k == 0011){
printf("%d",3);
}
if(k == 0100){
printf("%d",4);
}
if(k == 0101){
printf("%d",5);
}
if(k == 0110){
printf("%d",6);
}
if(k == 0111){
printf("%d",7);
}
if(k == 1000){
printf("%d",8);
}
if(k == 1001){
printf("%d",9);
}
if(k == 1010){
printf("%c", 'A');
}
if(k == 1011){
printf("%c", 'B');
}
if(k == 1100){
printf("%c", 'C');
}
if(k == 1101){
printf("%c", 'D');
}
if(k == 1110){
printf("%c", 'E');
}
if(k == 1111){
printf("%c", 'F');
}
}
}
I suggest you to take deep breath and start all over again. First remember, there's no need to convert anything to binary. Everything is binary already.
Maybe this little piece, which retrieves two hexadecimal characters could help you to get on to the track: (this is just one method)
int n = 165; // this is the number we want to display in hex (165 is 0xa5)
int i, hexChar;
i = n & 0xF; // bitwise AND with 00...001111
if(i < 10) // look up to ASCII table for more info
hexChar = i + 48; // character '0' is code 48, '1' is 49 etc.
else
hexChar = i + 55; // character 'A' is code 65, 'B' is 66 etc.
printf("Rigth most hex: %c\n", hexChar);
i = n >> 4; // shift all bits 4 steps to the right
i = i & 0xF; // bitwise AND with 00...001111
if(i < 10) // look up to ASCII table for more info
hexChar = i + 48; // character '0' is code 48, '1' is 49 etc.
else
hexChar = i + 55; // character 'A' is code 65, 'B' is 66 etc.
printf("Second hex: %c\n", hexChar);

How do I change the bytes of a 32-bit integer?

I'm trying to add two binary numbers together using only logical statements and binary arithmetic operators. But I'm confused on how to actually change the bits. It is mostly the out variable that I am trying to change, but it keeps getting zeroed every time I print it.
#include <stdio.h>
void execute_add(int a, int b){
int i = 0;
int bit;
int bit2;
int carryOut = 0;
int out = 10;
int overflow = 0;
for(i = 0; i <32 ; i++){
bit = (a >> i) & 1;
bit2 = (b >> i) & 1;
if(bit==1 && bit2==1 && carryOut == 0){
carryOut = 1;
out = 0 | (0x1 >> i);
}else if(bit==1 && bit2==1 && carryOut == 1){
carryOut = 1;
out = 1 | (0x1 >> i);
}else if(bit==0 && bit2==0 && carryOut == 0){
carryOut = 0;
out= 0 | (0x1 >> i);
}else if(bit==0 && bit2==0 && carryOut == 1){
carryOut = 0;
out = 1 | (0x1 >> i);
}else if(bit==1 && bit2==0 && carryOut == 0){
carryOut = 0;
out = 1 | (0x1 >> i);
}else if(bit==1 && bit2==0 && carryOut == 1){
carryOut = 1;
out = 0 | (0x1 >> i);
}else if(bit==0 && bit2==1 && carryOut == 0){
carryOut = 0;
out = 1 | (0x1 >> i);
}else if(bit==0 && bit2==1 && carryOut == 1){
carryOut = 1;
out = 0 | (0x1 >> i);
}else{
}//if else
}//for loop
printf("\n");
bit = (a >> 31) & 1;
bit2 = (a >> 31)& 1;
int bit3 = (out >> 31) & 1;
if( bit == 1 && bit2== 1 && bit3 == 0){
overflow = 1;
}else if (bit == 0 && bit2 == 0 && bit3 == 1){
overflow = 1;
}else{
}//overflow check
int j;
int g = 0;
for(j = 31; j>=0; j--){
if(g%4==0 && g!=0){
printf(" ");
}
bit2 = (out >> j) & 1;
printf("%d", bit2);
g++;
}
printf("\n");
}
int main (){
int a = 34;
int b = 17;
execute_add(a, b);
return 0;
}
With each of these statements in your for loop:
out = 0 | x;
You're resetting out, and clearing away all the work you've already done. You probably mean to do:
out = out | x
Or, equivalently,
out |= x
You also are right-shifting 1 all over the place, which is not what you're looking for; for any shift greater than zero, that's going to give you zero. I think you're often looking for a left-shift where you use a right shift.
I would second kaylum's comment about using a debugger; even if you flip the appropriate shifts and | with out properly, you're still going to have logic errors that will be easily fixed with a debugger.

Send a variable to a function and modify this variable in C

I have the following vars:
char seed[NBITS + 1], x0[NBITS + 1], y0[NBITS + 1], z0[NBITS + 1], dT0[NBITS + 1];
And i want to change it values on this function:
void lfsr(char *bin, char *output)
{
//bits significativos para fazer o xor NBITS -> NBITS,126,101,99;
int bits[4];
int bit;
if(bin[0] == '0')
bits[0] = 0;
else if(bin[0] == '1')
bits[0] = 1;
if(bin[2] == '0')
bits[1] = 0;
else if(bin[2] == '1')
bits[1] = 1;
if(bin[21] == '0')
bits[2] = 0;
else if(bin[21] == '1')
bits[2] = 1;
if(bin[19] == '0')
bits[3] = 0;
else if(bin[19] == '1')
bits[3] = 1;
bit = bits[0] ^ bits[1] ^ bits[2] ^ bits[3] ^ 1;
//reconstruir o vector de char depois do lfsr
for(int i = 127; i >= 1; i--)
{
bin[i] = bin[i - 1];
}
bin[0] = (char)(48 + bit);
output = bin;
}
The way that I put the value in y0 from x is, for example, calling the lfsr functions like this:
lfsr(x0, y0);
What am I doing wrong?
I have to do 3 Fibonacci Linear Feedback Shift Register starting from x0.
x0 = 10101010101010
y0 = lfsr(101010101010)
z0 = lfsr(y0)
dT0 = lfsr(z0);
The results are good, but when I do the above code the value of x0 will be the same as dT0 if i use pointers.
Can anyone help me?
Thanks. Cumps!
Consider the following:
The numbers correspond to the taps. The bits are actually 15..0, left to right. The following is my implementation of the Fibonacci Linear Feedback Shift Register:
#include <stdio.h>
uint16_t fibLfsr(const uint16_t num)
{
uint16_t tempNum;
tempNum = (num) ^ (num >> 2) ^ (num >> 3) ^ (num >> 5);
tempNum = (tempNum & 0x1) << 15;
tempNum = (tempNum | (num >> 1));
return tempNum;
}
int main(void)
{
uint16_t testNum = 0xACE1;
printf("%#X\n", testNum);
testNum = fibLfsr(testNum);
printf("%#X\n", testNum);
return 0;
}
I'm not quite sure why you're using strings and converting them to binary. If this is necessary, you'll need some of the standard library APIs in stdlib and string to convert the string to an uint16_t before calling fibLfsr() and back to a string afterwards.

How to generate all possible subsequences including Non-continuous subsequences of a string using C

For example,
char str[20];
str="ABCD";
Output :
1 - A, B, C,D
2 - AB,AC, AD BC, BD, CD.
3 - ABC, ABD, BCD.
4 - ABCD.
The sub-sequences are generated only in left to right fashion. Thanks :)
#include<stdio.h>
#include <conio.h>
#include<string.h>
int sub[10];
void next(int max, int length) {
int pos = length - 1,a;
//find first digit that can be increased
while(pos >= 0)
{
if(sub[pos] == max - (length - 1 - pos))
pos--;
else
break;
}
sub[pos]++; //increase digit
//update other digits
for( a = pos+1; a < length; a++)
sub[a] = sub[a-1] + 1;
}
int main()
{
char word[100];
printf("Enter a word = ");
scanf("%s",word);
int max = strlen(word) - 1,n,i,a,b;
for(n=1; n <= max+1; n++)
{
printf("\n");
for(i = 0; i < n; i++)
{
sub[i] = i;
}
for(a = 0; ; a++)
{
for(b=0; b < max+1; b++)
printf("%c",word[sub[b]]);
printf("\n");
if(sub[0] == max - (n - 1))
break;
else
next(max, n);
}
printf("\n");
}
return 0;
}
This code only produces sub-sequences of the length equal to the length of the string and it also repeats a particular character.
not the cleanest, most effective code, but this'll do :D
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <math.h>
char *printForMask(int mask, char *str)
{
int i = 0;
int j = 0;
char *maskedString = (char *)malloc(sizeof(char) * strlen(str) + 1);
for (; mask > 0; mask >>= 1, j++) {
if (mask & 1)
maskedString[i++] = str[j];
}
maskedString[i] = '\0';
return maskedString;
}
int main()
{
char str[20] = "ABCD";
int mask = 1;
int maskLen = 1;
int stringLen = strlen(str);
for (maskLen = 1; maskLen <= stringLen; maskLen++) {
printf("%d ", maskLen);
for (mask = (int)pow(2,maskLen) - 1; mask <= (int) pow(2, stringLen) - 1; mask <<= 1) {
char *temp = printForMask(mask, str);
printf ("%s%s", temp, (mask << 1 <= (int) pow(2, stringLen) - 1) ? ", " : "\n");
free(temp);
}
}
return 0;
}
EDIT
for the string ABCD
str[0] = 'A'
str[1] = 'B'
str[2] = 'C'
str[3] = 'D'
right?
So What I'm doing is using the binary representation of a integer 2^strlen(str) - 1
which in this case would be 2^4 - 1 = 15 = 0b1111
In the first for-loop of the main function, I increase the mask, meaning
start off with a mask = 0b0001, for each iteration of the loop, increase the mask to mask = 0b1111
And in the inner for loop, I shift the mask so that something like this happens
mask = 0b0001 //A
mask = 0b0010 //B
mask = 0b0100 //C
mask = 0b1000 //D
//The inner loop will finish here, and the mask length will become 2
mask = 0b0011 //AB
mask = 0b0110 //BC
mask = 0b1100 //CD
//etc. The string representation is made by the function printForMask()

Resources