Background on what the code is supposed to do, vs what I am achieving.
So the dec2bin function is supposed to get the values/numbers decimal from the array dec_nums[]={0, 1, 77, 159, 65530, 987654321};
the function is supposed to convert the value to binary numbers and print it out.
the conversion is done correctly however, it prints the binary backward.
Can someone help me on figuring out what the problem is, or if there is another way to achieve the correct results?
int main() {
int dec_nums[] = {0, 1, 77, 159, 65530, 987654321};
int i;
printf("=== dec2bin ===\n");
for (i = 0; i < sizeof(dec_nums) / sizeof(int); i++)
dec2bin(dec_nums[i]);
return 0;
}
void dec2bin(int num) {
int saveNum = num;
if (saveNum == 0) {
printf("\nBinary Number of %d", saveNum);
printf(" = 0");
} else {
int number;
int i;
printf("\nBinary Number of %i", saveNum);
printf(" = ");
for (i = 0; num > 0; i++) {
number = num % 2;
num = num / 2;
printf("%i", number);
}
printf("\n");
}
}
For bit fiddling unsigned types are preferrable, you avoid any kinds of problems with undefined behaviour due to under-/overflow.
Apart from, you can operate on bit masks:
for(unsigned mask = 1u << sizeof(mask) * CHAR_BIT - 1; mask; mask >>= 1)
{
unsigned bit = (value & mask) != 0;
// print it
}
CHAR_BIT is the value of bits within a char and comes from header limits.h, typically (but not necessarily) it is 8, with typically four bytes for ints you initialise the mask to 1 << 31 and further on shift it downwards until it reaches 1 << 0, i. e. 1, which is the last value yet considered. Yet another shift moves the single bit set out of the mask, so you get 0 and the loop aborts.
Above code will print leading zeros, you might prepend another loop that simply shifts down until the first 1-bit is met if you want to skip them.
This variant starts at most significant bit; by % 2 you always get the least significant bit instead – which is why you got the inverse order.
Side note: Getting length of an array is better done as sizeof(array)/sizeof(*array) – this avoids errors if you need to change the underlying type of the array...
A simple solution would be to write to bits into a char array, starting from the end of the array, the same way that we would do by hand.
Your dec2bin function would become (only minimal changes, with comments for added or changed lines):
void dec2bin(int num)
{
// declare a char array of size number_of_bits_in_an_int + 1 for the terminating null
char bin[sizeof(int) * CHAR_BIT + 1];
char* ix = bin + sizeof(bin) - 1; // make ix point to the last char
*ix-- = '\0'; // and write the terminating null
int saveNum = num;
if (saveNum == 0)
{
printf("\nBinary Number of %d", saveNum);
printf(" = 0");
}
else
{
int number;
int i;
printf("\nBinary Number of %i", saveNum);
printf(" = ");
for (i = 0; num > 0; i++)
{
number = num % 2;
num = num / 2;
*ix-- = '0' + number; // just write the bit representatin
}
printf("%s\n", ix+1); //print the binary representation
}
}
That is enough to get the expected result.
Related
I am very new to Coding. Here is a program that I wrote to convert decimal to binary
but there is one problem I am getting the result but it's in reverse
Example: Binary of 122 is 1111010 and I'm getting output 0101111.
Can anyone please tell me is it possible to reverse the output in my code?
Or what changes can I make in the following to get the correct output?
#include<stdio.h>
int main()
{
int n, q, r;
printf("Enter the decimal Number : ");
scanf("%d", &n);
int num=n;
while(n!=0)
{
r=n%2;
q=n/2;
printf("%d", r);
n=q;
}
return 0;
}
Seems like you are new to coding. It doesn't matter here is the problem.
Converting decimal to binary is like this,
eg:
division by 2
quotient
reminder
bit
10/2
5
0
0
5/2
2
1
1
2/2
1
0
2
1/2
0
1
3
=(1010)
So the output should have digits from bottom to top of the reminder column. Your output is printed from top to bottom.
See the code below where you need an array in order to store reminders and print the array in reverse order so you get the output you need
#include<stdio.h>
#include<stdlib.h>
int main(void){
int a[10],n,i;
printf("Enter the decimal Number : ");
scanf("%d",&n);
for(i=0;n>0;i++)
{
a[i]=n%2;
n=n/2;
}
printf("\nBinary of Given Number is=");
for(i=i-1;i>=0;i--)
{
printf("%d",a[i]);
}
return 0;
}
void display(unsigned n)
{
if(n == 0) return;
display(n /2);
printf("%d", n % 2);
}
and example usage:
https://godbolt.org/z/ahGPc74nf
As a homework: how to correctly handle 0?
Or not recursive version. This one can print or not leading zeroes:
void display(unsigned n, int printzeroes)
{
unsigned mask = 1 << (CHAR_BIT * sizeof(mask) - 1);
int print = printzeroes;
while(mask)
{
if(n & mask)
{
print = 1;
}
if(print) printf("%d", !!(n & mask));
mask >>= 1;
}
}
And usage: https://godbolt.org/z/7Eq71TMWb
First of all, please note that all numbers in a C program are to be regarded as binary. It's a common misconception among beginners that different number formats somehow co-exist in the executable program. But everything there is raw binary.
Sure the programmer may write numbers in different formats 7, 07 or 0x7 in the source code, but they get translated to binary by the compiler. Therefore, converting between binary and "x" doesn't make sense, because everything is already binary. You may however, convert from binary to a decimal string or similar, for the purpose of displaying a number to the user etc.
With that misconception out of the way - yes, you can create a binary string with the method you picked, dividing by ten and checking the remainder. The problem with that approach is that you'll get the most significant digit first. This is why you get the number backwards. So in order to do that, you'd have to store down the string in a character array first, before displaying it.
A more convenient way would be to use the "bitwise" operators like & and shift to mask out bit by bit in the data. Basically this:
if(n & (1u << bit)) // 1u to avoid shifting signed type
printf("1");
else
printf("0");
Where bit is the bit position 7,6,5... down to 0. If we prefer an up-counting loop instead, we can tweak the code into:
for(size_t i=0; i<8; i++)
{
size_t mask = 1u << 8-i-1;
...
}
And finally we can make the output a bit more compact, which is just a stylistic concern:
for(size_t i=0; i<8; i++)
{
size_t mask = 1u << 8-i-1;
printf("%c", n & mask ? '1' : '0');
}
If you aren't dead certain about C operator precedence, then use parenthesis, which is perfectly fine too:
for(size_t i=0; i<8; i++)
{
size_t mask = 1u << (8-i-1);
printf("%c", (n & mask) ? '1' : '0');
}
Here's the homework demanded by 0___________:
void printbin(int n)
{
static int depth;
if (n) ++depth, printbin(n / 2), --depth;
else if (depth) return; // print leading 0 only for n = 0
printf("%d", n % 2);
}
A leading 0 is not printed unless on the topmost recursion level.
You could maybe create an array of size 32 and keep adding the digits to the array. Or create a int variable and add the digits to the variable.
int result = 0;
while(n!=0)
{
r=n%2;
n=n/2;
result = result*10+r;
}
I need to write a function that subtracts digits.
If user inputs 2345, the output should be 111 (5-4, 4-3, 3-2); another example would be 683, where the output should be 25 (3-8(abs value is taken), 8-6).
I have wrote the following code which works only when the size of the array is declared.
int subtraction(int arr[], int size) {
int sub = 0;
for (int i = 0; i < size-1; i++) {
sub = sub * 10 + abs(arr[i] - arr[i+1]);
}
return sub;
}
However, the number that the user inputs is random and can have various digits, so I don't know what limit to put in the for loop.
For example:
int arr[] = {1, 2, 55, 56, 65, 135}, i;
subtraction(arr, 6);
for (i=0; i<6; i++)
printf("%d ", arr[i]);
expected output: 0 0 0 1 1 22
The function is supposed to subtract the second-to-last digit from the last one, by the way , / from right to left / from a random number that the user inputs ; for example if the input is 5789, the output is supposed to be 211 (9-8, 8-7, 7-5); if user inputs a negative number, the program should take it's absolute value and then do the subtracting. If user input is a one digit number the result should be 0.
The function I wrote only works when the size of the array is declared. I don't know how to make it work when the size is undeclared (pointers and malloc are required I believe, as that's what I managed to find out by googling for ages, but unfortunately, I don't know how to do it).
please help?
You are not actually changing any values, here is the line you need to look at.
sub = sub * 10 + abs(arr[i] - arr[i+1]);
As you are printing the array you actually need to store the calculated value in the array again.
#include <stdio.h>
#include <stdlib.h>
int subtract(int n)
{
int factor = 1;
int total = 0;
int lastPlace = n%10;
n /= 10;
while (n>0)
{
total += (factor * abs((n%10) - lastPlace));
factor *= 10;
lastPlace = n%10;
n /= 10;
}
return total;
}
void subtractArray(int* arr, unsigned int size)
{
for (int i=0; i<size; ++i)
{
if (arr[i] < 0)
arr[i] = abs(arr[i]);
arr[i] = subtract(arr[i]);
}
}
int main()
{
int arr[] = {1, 2, 55, 56, 65, 135};
int size = sizeof(arr)/ sizeof(arr[0]);
subtractArray(arr, size);
for (int i=0; i<size; ++i)
{
printf("%d ", arr[i]);
}
return 0;
}
Here is a simple code that solve your problem :)
#include <stdio.h>
#include <stdlib.h>
int *subtraction(int arr[], int size)
{
int *sub = calloc(sizeof(int*) , size), i = 0, rev; //allocating memory
for (i = 0; i < size; i++)
{
rev = 0;
arr[i] = abs(arr[i]);
for (int a = 0; arr[i] != 0; arr[i] /= 10)
rev = (rev * 10) + (arr[i] % 10);
for (i; (rev / 10) != 0; rev /= 10) //the loop ends when rev = 0
sub[i] = ((sub[i] * 10) + abs( (rev % 10) - ((rev / 10) % 10) )); //easy math => for example rev = 21 > sub[i] = (0 * 10) + ( (21 % 10) - ((21 / 10) %10)) = abs(1 - 2) = 1;
}
return sub;
}
int main()
{
int arr[] = {-9533, 7, -19173}, i;
int len = sizeof(arr)/sizeof(arr[0]); //size of arr
int *sub = subtraction(arr, len);
for(int i = 0; i < len; i++) //for test
printf("%d ", sub[i]);
return 0;
}
output for {1, 2, 55, 56, 65, 135}:
0 0 0 1 1 22
output for {987654321, 123456789, 111111111} :
11111111 11111111 0
output for {38279}:
5652
output for {-9533, 7, -19173}:
420 0 8864
Well as for the array of undefined size. What you probably want is a dynamically allocated array.
Here we get the number of array elements based on user input, within limits, of course.
first we're gonna get the number from the user using fgets() which will give us a string, then we'll use strtol() to convert the number part to scalar (int). you can use scanf("%d", &n) if you want.
Then we can count the digits from that number, and that value will be the number of elements of our array.
#include <stdio.h>
#include <stdlib.h> //for strtol(), malloc() and NULL guaranteed
//you may also want to add
#include <limits.h>
#include <errno.h>
#define MAX_STRLEN 12 // can hold all digits of INT_MAX plus '\0' and a posible, AND very likely, '\n'
#define DEC 10 // for strtol base argument
/*
* I'm lending you my old get_n_dits() function that I used to count decimal digits.
*/
int get_n_dits(int dnum) {
unsigned char stop_flag = 0; //we'll use to signal we're done with the loop.
int num_dits = 1, dpos_mult = 1; //num_dits start initialized as 1, cause we're pretty sure that we're getting a number with at least one digit
//dpos_mult stands for digital position multiplier.
int check_zresult; //we'll check if integer division yields zero.
/**
* Here we'll iterate everytime (dnum / dpost_mult) results in a non-zero value, we don't care for the remainder though, at least for this use.
* every iteration elevates dpost_mult to the next power of ten and every iteration yielding a non-zero result increments n_dits, once we get
* the zero result, we increment stop_flag, thus the loop condition is no longer true and we break from the loop.
*/
while(!stop_flag) {
dpos_mult *= 10;
check_zresult = dnum / dpos_mult;
(check_zresult) ? num_dits++ : stop_flag++;
}
return num_dits;
}
int main(void) {
int num, ndits; //we'll still using int as per your code. you can check against INT_MAX if you want (defined in limits.h)
int *num_array = NULL; //let's not unintentionally play with an unitialized pointer.
char *num_str = malloc(MAX_STRLEN); //or malloc(sizeof(char) * MAX_STRLEN); if there's any indication that (sizeof(char) != 1)
printf("please enter a number... please be reasonable... or ELSE!\n");
printf(">>> ");
if(!fgets(num_str, MAX_STRLEN, stdin)) {
fprintf(stderr, "Error while reading from STDIN stream.\n");
return -1;
}
num = (int)strtol(num_str, NULL, DEC); //convert the string from user input to scalar.
if(!num) {
fprintf(stderr, "Error: no number found on input.\n");
return -1;
}
ndits = get_n_dits(num);
if(ndits <= 0) {
fprintf(stderr, "Aw, crap!\n");
return -1;
}
printf("number of digits: %d\n", ndits);
num_array = malloc(sizeof(int) * ndits); //now we have our dynamically allocated array.
return 0;
}
I am writing a program that converts a given bit string (up to 32-bits) into decimal assuming the input is given in unsigned magnitude and two's complement. I am reading each bit in from the user one char at a time and attempting to store it into an array, but the array doesn't have a required size. Is there a way to get the array to go through the loop without the array size being known? I also am trying to figure out a way to not use the pow and multiplication functions. I am posting my code below, if you have any ideas please
#include "stdio.h"
#include "math.h"
#define MAX_BITS 32
#define ENTER '\n'
#define NUMBER_TWO 2
int main()
{
int unsignedMag;
int twosComp;
int negation[n];
int bitStore[n];
char enter;
//Input from the User
printf("Enter up to 32 bits (hit 'enter' to terminate early): ");
//Reads the first bit as a character
char bit = getchar();
while (getchar != enter) {
bit = bit - '0';
scanf("%c", &bitStore[bit]);
getchar();
}
//Terminates if user hits enter
if (bit == enter) {
return 0;
}
//Continue through code
else {
//Loop to calculate unsigned magnitude
for (int i = 0; i < bitStore[i]; i++) {
unsignedMag = unsignedMag + (bitStore[i] * pow(NUMBER_TWO, i));
}
//Loop to calculate complete negation
for (int j = 0; j < bitStore; j++) {
negation[j] = ~bitStore[j]
}
negation = negation + 1;
for (int l = 0; l < negation; l++) {
twosComp = twosComp + (negation[l] * pow(NUMBER_TWO, l));
}
}
return 0;
}
"Is there a way to get the array to go through the loop without the array size being known?"
No. Array sizes are fixed at the point the array is declared and the size is knownable: e.g. #Observer
size_t size = sizeof bitStore/sizeof bitStore[0];
Instead, since code has "given bit string (up to 32-bits) ", define the array as size 32 (or 33 is a string is desired).
Keep track of how much of the array was assigned.
//int bitStore[n];
int bitStore[MAX_BITS];
int count = 0;
// char bit = getchar();
int bit = getchar(); // Use `int` to account for potentially 257 different values
//while (getchar != enter) {
while (count < MAX_BITS && (bit == '0' || bit == '1')) {
bit = bit - '0';
// Do not read again, instead save result.
//scanf("%c", &bitStore[bit]);
bitStore[count++] = bit;
// getchar();
bit = getchar();
}
to not use the pow and multiplication functions.
Simply add or multiply by 2 via a shift. It is unclear why OP has a goal of not using "multiplication". I see little reason to prohibit *. A good compiler will emit efficient code when the underlying multiplication is expensive as *2 is trivial to optimize.
// int unsignedMag;
unsigned unsignedMag = 0; // initialize
// for (int i = 0; i < bitStore[i]; i++) {
for (int i = 0; i < count; i++) {
// preferred code, yet OP wants to avoid * for unclear reasons
// unsignedMag = unsignedMag*2 + bitStore[i];
unsignedMag = unsignedMag + unsignedMag + bitStore[i];
}
pow() is good to avoid for many reasons here. Most of all, using double math for an integer problem runs into precision issues with wide integers.
converts a given bit string (up to 32-bits) into decimal
Note that a bitStore[] array is not needed for this task. Simply form unsignedMag as data is read.
I want to reiterate the fact that I am not asking for direct code to my problem rather than wanting information on how to reach that solution.
I asked a problem earlier about counting specific integers in binary code. Now I would like to ask how one comes about counting the maximum block length within binary code.
I honestly just want to know where to get started and what exactly the question means by writing code to figure out the "Maximum block length" of an inputted integers binary representation.
Ex: Input 456 Output: 111001000
Number of 1's: 4
Maximum Block Length: ?
Here is my code so far for reference if you need to see where I'm coming from.
#include <stdio.h>
int main(void)
{
int integer; // number to be entered by user
int i, b, n;
unsigned int ones;
printf("Please type in a decimal integer\n"); // prompt
fflush(stdout);
scanf("%d", &integer); // read an integer
if(integer < 0)
{
printf("Input value is negative!"); // if integer is less than
fflush(stdout);
return; // zero, print statement
}
else{
printf("Binary Representation:\n", integer);
fflush(stdout);} //if integer is greater than zero, print statement
for(i = 31; i >= 0; --i) //code to convert inputted integer to binary form
{
b = integer >> i;
if(b&1){
printf("1");
fflush(stdout);
}
else{
printf("0");
fflush(stdout);
}
}
printf("\n");
fflush(stdout);
ones = 0; //empty value to store how many 1's are in binary code
while(integer) //while loop to count number of 1's within binary code
{
++ones;
integer &= integer - 1;
}
printf("Number of 1's in Binary Representation: %d\n", ones); // prints number
fflush(stdout); //of ones in binary code
printf("Maximum Block Length: \n");
fflush(stdout);
printf("\n");
fflush(stdout);
return 0;
}//end function main
Assuming you are looking for the longest run of 1's.
Heres how you do it for 32bits. You should be able to extend this idea to arbitrarily long bitstreams.
int maxRunLen(uint32_t num) {
int count = 0;
int maxCount = 0;
while(num) {
if(num & 1) count++;
else {
if( count > maxCount) maxCount = count;
count = 0;
}
num >>=1;
}
if( count > maxCount) maxCount = count;
return maxCount;
}
The idea is to test each bit in order to determine if it is a 1 or not. If it is 1, increment the count. Otherwise it is the end of a run and in this case check if the previous run is longer than any previous maximum run and reset the count.
The way to test a bit is using masking. In the above example the lowest order bit tested by
num & 1
To test the next bit in the number you move all the bits 1 bit to the right which is called a shift. More explicitly in this a case a logical right shift (>>). Example bit pattern 0110 becomes 0011. This is done in the above example:
num >>= 1;
Which is equivalent to:
num = num >> 1;
Try this:
int max_run_of_ones (unsigned x)
{
int max_run = 0;
int cur_run;
while (x != 0) {
// skip right-most zeros
while ((x & 1) == 0) {
x >>= 1;
}
// skip and measure right-most run of ones
cur_run = 0;
while ((x & 1) == 1) {
cur_run++;
x >>= 1;
}
if (cur_run > max_run) max_run = cur_run;
}
return max_run;
}
From looking at your code, it looks like you want to know the count of the bits set.
This is a guess...
Credit goes to Ratko Tomic for this. The guy is brilliant at bit operations.
int countBits( int value )
{
int n = 0;
if( value )
{
do
{
n++;
} while( 0 != (value = value & (value - 1) ) );
}
return( n );
}
This should solve it in python, using string operations...
The main point of this is to help others with understanding what you're trying to accomplish.
import re
number = 500
binary_repr = bin(number)[2:] # '111110100'
blocks = re.split(r'0+', binary_repr) # ['11111', '1', '']
block_lengths = [len(x) for x in blocks] # [5, 1, 0]
maximum_block_length = max(block_lengths) # 5
I am currently trying to make an implementation of the encryption scheme DES but I've run into a problem early on. This is the first time I have ever performed bitwise manipulations in a program and I am not very proficient with C either. I apply a permutation and its inverse and the result is not the same as the input.
What I am trying to do is to apply the initial permutation and inverse permutation on a block of 64 bits. I have my block of 64 bits that I want to encrypt in the array input. According to the permutation table IP I take the first bit in the first byte and put it as bit 58 in the permutation. Bit 2 is sent to bit 50 and so on. After the permutation the result is divided in half and the sides swapped. This will enable it to be put back using the same algorithm but with the IPinverse table.
include <stdio.h>
include <stdlib.h>
static unsigned char Positions[8] = {1,2,4,8,16,32,64,128};
int main()
{
unsigned char input[8] = {'a','b','c','d','e','f','g','h'};
unsigned char permutation[8];
unsigned char inverse[8];
int i;
for (i = 0; i < 8; i++) {
permutation[i] = 0;
inverse[i] = 0;
}
int IP[8][8] ={{58,50,42,34,26,18,10,2},
{60,52,44,36,28,20,12,4},
{62,54,46,38,30,22,14,6},
{64,56,48,40,32,24,16,8},
{57,49,41,33,25,17, 9, 1},
{59,51,43,35,27,19,11,3},
{61,53,45,37,29,21,13,5},
{63,55,47,39,31,23,15,7}};
int IPinverse[8][8] ={{40,8,48,16,56,24,64,32},
{39,7,47,15,55,23,63,31},
{38,6,46,14,54,22,62,30},
{37,5,45,13,53,21,61,29},
{36,4,44,12,52,20,60,28},
{35,3,43,11,51,19,59,27},
{34,2,42,10,50,18,58,26},
{33, 1,41, 9,49,17,57,25}};
printf("\n Before: \n");
for (i = 0; i < 8; i++) {
printf(" %c", input[i]);
}
// Initial permutation
int bit, newpos;
unsigned char desiredbit;
for (bit = 0; bit < 64; bit++) {
// Get the location for where the bit will be sent and translate it to array index
newpos = ((int)IP[bit/8][bit%8])-1;
// examine the bit we're currently considering
desiredbit = input[bit/8] & Positions[bit%8];
// if equal to zero that means no change necessary
if (desiredbit != 0) {
// else it was a 1 and we need to set the appropriate bit to 1
desiredbit = Positions[newpos%8];
permutation[newpos/8] = desiredbit ^ permutation[newpos/8];
}
}
printf("\n Permutation: \n");
for (i = 0; i < 8; i++) {
printf(" %c", permutation[i]);
}
// Perform swap
unsigned char tempcopy[4] = {0,0,0,0};
int j;
for (j = 0; j < 4; j++) {
tempcopy[j] = permutation[j+4];
}
for (j = 0; j < 4; j++) {
permutation[j+4] = permutation[j];
permutation[j] = tempcopy[j];
}
// Reverse Permutation, remember to swap left side with right
for (bit = 0; bit < 64; bit++) {
newpos = ((int)IPinverse[bit/8][bit%8])-1;
desiredbit = permutation[bit/8] & Positions[bit%8];
if (desiredbit != 0) {
desiredbit = Positions[newpos%8];
inverse[newpos/8] = desiredbit ^ inverse[newpos/8];
}
}
printf("\n Reverse Permutation: \n");
for (i = 0; i < 8; i++) {
printf(" %c", inverse[i]);
}
return 0;
}
Your permutation contains indexes from 1 to 64, but the way you use them, they should be 0 to 63.
What's the swap for? If you permute, swap, then permute back, you won't reach the same place.
You need to verify that the permutation and reverse are indeed opposites. I'm surely not going to go over all the numbers and verify it.