Variable names with parameters [closed] - c

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 6 years ago.
Improve this question
So I have some code here that I have been studying. It converts decimal numbers to binary. The code runs smoothly but what's bugging me are the variables. The code is as follows:
#include <stdio.h>
int main()
{
long int decimalNumber, remainder, quotient;
int binaryNumber[100], i=1, j;
printf("Enter any decimal number: ");
scanf("%ld",&decimalNumber);
quotient = decimalNumber;
while (quotient!=0) {
binaryNumber[i++]= quotient % 2;
quotient = quotient / 2;
}
printf("Equivalent binary value of decimal number %d: ", decimalNumber);
for (j = i -1 ; j> 0; j--)
printf("%d",binaryNumber[j]);
return 0;
}
I really find the variables confusing. Can someone tell me what is actually happening with the variables? Especially the one with binaryNumber[100],binaryNumber[i++], binaryNumber[j], and the expression binaryNumber[i++] = quotient % 2

binaryNumber is an array of ints, i.e. of integers. It is of size 100. It goes from 0...99 (binaryNumber[0] is the first element and binaryNumber[99] is the last). The array can contain 100 integers, of different or equal values. They don't actually have to be of value 0...99 but anything else that is in the range of int (read comment).
When you perform int binaryNumber[100] you define this array.
When you perform binaryNumber[i++] you access the element in the location i of this array, and then increment i. Meaning you perform i = i + 1;.
Same goes for binaryNumber[j].
When you perform binaryNumber[i++] = quotient % 2 you assign the value of quotient % 2 to the binaryNumber array at position i like stated before (and increment i).
If you're wondering about the modulus operator (%) read here.

binaryNumber[100]: This is actually an array of 100 integers. The first integer in the array could be accessed by binaryNumber[0] etc.
binaryNumber[j]: This means the (j-1)th integer in the array.
binaryNumber[i++]: Lets say i=3 when this statement runs. binaryNumber[i++] is equivalent to binaryNumber[3], which is the 4th integer. However, after this statement is executed, i is incremented to 4.
quotient % 2:
% is actually the modulus operator. Example: 13 % 4 = remainder of 13/4 = 1.

binaryNumber[100] : it is an array , a sepuence of elements of type "long int" you can access a spesific element using "array[index] = value" .
binaryNumber[i++] : access the element nember i then increament i , example if i=1 then you acces binaryNumber[1] then i become 2 (after usage ).
binaryNumber[j] : access the element nember j , j is a variable and can be used as a index , then you will acces the element nember the current value of j .
binaryNumber[i++] = quotient % 2 : it tell the compiler to let the element nember i in the binaryNumber take the value of quotient % 2 that is the math modulos , like 9%2=1 ; 5%3=2 , the rest of the quotient pear 2
comment for more informations .

A simple way to do the conversion is a loop and shift. You can put it in a function to make the conversion look nice. Here is an example:
#include <stdio.h>
#include <stdlib.h>
#include <limits.h> /* for CHAR_BIT */
void binprn (const unsigned long v);
int main (int argc, char **argv) {
long unsigned a = argc > 1 ? strtoul (argv[1], NULL, 10) : 4327;
printf ("\n %lu decimal, binary: ", a);
binprn (a);
putchar ('\n');
return 0;
}
/** unpadded binary representation of 'v'. */
void binprn (const unsigned long v)
{
if (!v) { putchar ('0'); return; };
size_t sz = sizeof v * CHAR_BIT;
unsigned long rem = 0;
while (sz--)
if ((rem = v >> sz))
putchar ((rem & 1) ? '1' : '0');
}
Use/Output
$ ./bin/dec2bin
4327 decimal, binary: 1000011100111
$ ./bin/dec2bin 10
10 decimal, binary: 1010
$ ./bin/dec2bin 127
127 decimal, binary: 1111111

Related

Please suggest an optimization in this code without using pow() function ? This question was asked to me in the interview [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question does not appear to be about programming within the scope defined in the help center.
Closed 8 months ago.
Improve this question
when I give input as num=1, output should be 8
when I give input as num=2, output should be 16
when I give input as num=3, output should be 32
when I give input as num=4, output should be 64
and so on
Here is the code
#include <stdio.h>
#include <stdlib.h>
int main()
{
int num,b;
scanf("%d",&num);
num=num+2;
b=pow(2,num);
printf("%d",b);
return 0;
}
I tried writing my own pow() function, but interviewer did not accept the solution.
You can use bit shifting.
Firstly, let's idenitfy the pattern (which you already have, it seems): for any given num, we should print out 2 to the power of num+2.
Consider that we are working in base 2. (Most) Computers nowadays store numbers in binary. Consider the binary representation of 1, 2, 4, 8 and 16.
1 = 0b00001
2 = 0b00010
4 = 0b00100
8 = 0b01000
16 = 0b10000
Notice that for each power of 2, there is only one bit set to 1. For increasing powers of 2, this bit moves to the left. With C, we can achieve getting something like this with the left shift operator in O(1), computationally faster than the O(log num) or O(num) implementations of pow as a library function and your own implementation of pow.
Instead of b=pow(2, num), you can try b=1<<num instead. This way, when num = 3 for example, the bit will be shifted three times to get 0b01000 = 8.
A straightforward approach can look for example the following way using the bitwise left shift operator.
Pay attention to that you should define the result when the value of num (that should be of unsigned integer type) is equal to 0.
#include <stdio.h>
unsigned long long f( unsigned int n )
{
return n == 0 ? 1 : 8llu << ( n - 1 );
}
int main( void )
{
const unsigned int N = 5;
for ( unsigned int i = 0; i < N; i++ )
{
printf( "%llu ", f( i ) );
}
putchar( '\n' );
}
The program output is
1 8 16 32 64
If the goal is to optimize the pow() call, you can't really replaces this with shift operations on an integer type; then there will be lost of precision for high values of n.
However, it is quite easy to write a pow2() function for integer input; It just need to set the exponent value of a double variable (assuming it’s in IEEE 754 format). Example code:
#include <stdio.h>
double pow2i(int n)
{
short s[4] = { 0 }; // IEEE 754
s[3] = (short)((n + 0x3FF) << 4 ); // writing the exponent value
return *(double*)&s;
}
double f(int n)
{
return pow2i(n+2);
}
int main()
{
for( int i = 1; i < 201; i++ )
printf("f(%d): %.0f\n",i,f(i));
return 0;
}

No output for long long int variables

Here is a code snippet:
unsigned int m,n,a;
long long int c,p=0,q=0;
scanf("%u%u%u",&m,&n,&a);
while(m>0){
m-=a;
p++;
}
while(n>0){
n-=a;
q++;
}
c=p*q;
printf("%lld",c);
The above code does not work for any input. That is, it seems like it has crashed,though I could not understand where I'm mistaken. I guess the part with %lld in the printf has problems. But Ido not know how to fix it. I'm using code blocks.
Some expected outputs for corresponding inputs are as follows:
Input: 6 6 4
Output: 4
Input: 1000000000 1000000000 1
Output: 1000000000000000000(10^18).
APPEND:
So, I'm giving the link of the main problem below. The logic of my code seemed correct to me.
https://codeforces.com/contest/1/problem/A
As it's been pointed out in comments/answers the problem is that m and n is unsigned so your loops can only stop if m and n are a multiple of a.
If you look at the input 6 6 4 (i.e. m=6 and a=4), you can see that m first will change like m = 6 - 4 which leads to m being 2. So in the next loop m will change like m = 2 - 4 which should be -2 but since m is unsigned it will wrap to a very high positive number (i.e. UINT_MAX-1) and the loop will continue. That's not what you want.
To fix it I'll suggest you drop the while loops and simply do:
unsigned int m,n,a;
long long unsigned int c,p=0,q=0;
scanf("%u%u%u",&m,&n,&a);
p = (m + a - 1)/a; // Replaces first while
q = (n + a - 1)/a; // Replaces second while
c=p*q;
printf("%lld",c);
One problem with this solution is that the sum (m + a - 1) may overflow (i.e. be greater than UINT_MAX) and therefore give wrong results. You can fix that by adding an overflow check before doing the sum.
Another way to protect against overflow could be:
p = 1; // Start with p=1 to handle m <= a
if (m > a)
{
m -= a; // Compensate for the p = 1 and at the same time
// ensure that overflow won't happen in the next line
p += (m + a - 1)/a;
}
This code can then be reduced to:
p = 1;
if (m > a)
{
p += (m - 1)/a;
}
while(m>0){
m-=a;
p++;
}
will run until m is equal to 0, since it cannot be negative because it is unsigned. So if m is 4 and a is 6, then m will underflow and get the maximum value that m can hold minus 2. You should change the input variables to signed.
4386427 shows how you can use math to remove the loops completely, but for the more general case, you can do like this:
while(m > a) {
m-=a;
p++;
}
// The above loop will run one iteration less
m-=a;
p++;
Of course, you need to do the same thing for the second loop.
Another thing, check return value of scanf:
if(scanf("%u%u%u",&m,&n,&a) != 3) {
/* Handle error */
}
Using an unsigned type isn't always the best choice to represent positive values, expecially when its modular behavior is not needed (and maybe forgotten, which leads to "unexpected" bugs). OP's use case requires an integral type capable of store a value of maximum 109, which is inside the range of a 32-bit signed integer (a long int to be sure).
As 4386427's answer shows, the while loops in OP's code may (and should) be avoided anyways, unless a "brute force" solution is somehow required (which is unlikely the case, given the origin of the question).
I'd use a function, though:
#include <stdio.h>
// Given 1 <= x, a <= 10^9
long long int min_n_of_tiles_to_pave_an_edge(long int x, long int a)
{
if ( x > a ) {
// Note that the calculation is performed with 'long' values and only after
// the result is casted to 'long long', when it is returned
return 1L + (x - 1L) / a;
}
else {
return 1LL;
}
}
int main(void)
{
// Given a maximum value of 10^9, a 32-bit int would be enough.
// A 'long int' (or 'long') is guaranteed to be capable of containing at
// least the [−2,147,483,647, +2,147,483,647] range.
long int m, n, a;
while ( scanf("%ld%ld%ld", &m, &n, &a) == 3 )
{
// The product of two long ints may be too big to fit inside a long.
// To be sure, performe the multiplication using a 'long long' type.
// Note that the factors are stored in the bigger type, not only the
// result.
long long int c = min_n_of_tiles_to_pave_an_edge(m, a)
* min_n_of_tiles_to_pave_an_edge(n, a);
printf("%lld\n",c);
}
}

Getting the amount of decimals a number has in c?

I am trying to get the amount of decimals a number has in c: 0.0001 -> 4 decimals, 3,54235 -> 5 decimals, and so on (If you don't get it, the number of numbers behind the comma.) our teacher sais it can be done in two ways, using a string and not using a string. I figured i would go ahead not using a string because I have NO experiance with strings.
So this is what I came up with
int funzione1(float decimals){
int x=1,c=0,y=1;
while (x!=0){
if((decimals - y) > 0){
y = y / 10;
c++;
}else{
decimals = decimals - y;
}
if(decimals == 0)
x=0;
}
return c-1;
}
When calling the function it should return the amount of decimals I figured, but it does not, actually it gets stuck in an infinite loop.
the Idea behind this code was to for every number in the "string" of numbers to get them to 0 and then check if the total number was 0
3.456 c=0
0.456 c=1
0.056 c=2
0.006 c=3
0.000 return c
But That leaves me with two problems 1 how to detirmine tha amount of numbers before the comma for like 5564.34234 this code will not work because it will count to 8 before the full number is a solid 0. and therefor not return the right number of decimals.2. the code I designed isn't working. Just gets stuck in an infinite loop. I don't know where the infiniteness of the loop is created.
How do i get this code to work?
PS. I found this article about this problem in Java: How to find out how many decimals a number has? but it is using strings and I would not like that because of the fact that I don't know how to use strings.
edit: Here is another piece of code i tried and which faild really bad givving an output of 50 when you enter a number higher than 1 and 0 if the number is lower than 0(I don't get it, not a little bit) anyway here is the code:
int funzione1(float decimals){
int i=0;
while(decimals!=((int)decimals)){
i++;
decimals=decimals*10;
}
return i;
}
If you don't care about rounding then you don't need to count the number of decimal places, you can just count the number of binary places. This is because 10 contains 2 as a factor exactly once so 10^n and 2^n have the same number of 2s as factors. The fastest way to count the number of binary places is to get the exponent of the floating point number.
e.g. binary 0.001 takes 3 decimal places to represent 0.125, 0.0001 takes 4 0.0625.
You can either get the fractional part of the value and keep multiplying by 2 and removing the integer as people have suggested doing with 10 (it will give you the same answer).
Or you can have a bit more fun over optimising the solution (the places function does most of the work):
#include <math.h>
int saturateLeft (unsigned int n) {
n |= (n << 1);
n |= (n << 2);
n |= (n << 4);
n |= (n << 8);
n |= (n << 16);
return n;
}
int NumberOfSetBits(int i)
{
i = i - ((i >> 1) & 0x55555555);
i = (i & 0x33333333) + ((i >> 2) & 0x33333333);
return (((i + (i >> 4)) & 0x0F0F0F0F) * 0x01010101) >> 24;
}
int places (double num) {
int exponent;
float mantissa = frexp (num, &exponent);
/* The answer we are looking for is given by the
(number of bits used by mantissa) - the exponent.
*/
unsigned intMantissa = scalbnf (mantissa, 32);
/* Could also be got by doing:
intMantissa = *(unsigned *)&mantissa << 9;
*/
/* To work out how many bits the mantissa covered we
need no gaps in the mantissa, this removes any gaps.
*/
intMantissa = saturateLeft (intMantissa);
int bitCount = NumberOfSetBits (intMantissa);
/* bitCount could also be found like this:
intMantissa = ~intMantissa;
int bitCount = 32 - ilogb (intMantissa) - 1;
*/
int result = bitCount - exponent;
if (result < 0)
return 0;
return result;
}
The bitCounting algorithm was found here.
Your best bet would be to read the input as string and just count the digits after '.'. Floating point numbers are not exact representation i.e. the decimal values are stored in binary internally and may not exactly represent the true decimal value. However every binary representation is some decimal number with finite digits.
Have a look at this answer in SO.
Here's an idea:
Start with a floating point number, say a = 3.0141589
Make the part before the decimal point 0 by subtracting the integral part, leaving 0.0141589
In a loop, multiply a by 10 and save the integral part, this gives you a list of digits from 0 to 9.
From this list, derive the number of decimals
There are some interesting details in this algorithm for you to find out, and I won't spoil the fun or surprises waiting for you.
Consider my string-based solution:
#include <stdio.h>
#include <string.h>
#include <locale.h>
#include <math.h>
#include <float.h>
int countDecimals(double x)
{
int cnt;
char * ptr;
char str[20] = {0};
// take fractional part from x
double ip;
double fp = modf (x , &ip);
// printf("%lg + %.15lg\n", ip, fp); // uncomment for debugging
// to be sure that Decimal-point character is '.'
setlocale(LC_NUMERIC, "C");
// make string from number's fractional part asking maximum digits (DBL_DIG)
sprintf(str,"%.*lg", DBL_DIG, fp);
// find point
if( ptr = strchr(str, '.') )
{
// calculate length of string after point
// length - (point position from beginning) - point = number of decimals
cnt = strlen(str) - (ptr - str) - 1;
}
else
{
cnt = 0;
}
return cnt;
}
int main (void)
{
double fn;
printf("Enter a float number: ");
scanf("%lf", &fn);
printf("Your number has %d decimals.\n" , countDecimals(fn) );
return 0;
}
But you should remember about possible rounding and accuracy errors.
Note: I have used double type, for float function modff should be used instead of modf, and FLT_DIG instead of DBL_DIG

C: Convert int array representing bits of a number into a single Int?

I am a beginner in C and wish to know how to convert an array of numbers that represent the bits of a number into the integer it represents.
I searched online but only found char array to int.
I am making converter and need to int array to toggle the bit values from 1 to 0 and vice versa(ie binary). So far i have managed to make the array integers toggle, but I cannot figure out how to change the array of numbers into the single number the array represents. I need this integer so i can convert it into a decimal number which the user can view.
Is there any simple solution to this?
bin= integer variable to store the binary number
arrbin = integer array to store the state of the bit ie(00000000)
for (i = 0; i < 8; ++i )
{
bin = bin + (10 * arrbin[i]);
}
EDIT: I think i see the problem now, instead of the values being implemented every exponent of 10 up, the numbers were only being multiplied by 10. will try and see if this fixes it.
EDIT #2: I dont mean conversion of binary to decimal. I meant conversion of array of numbers ie{1,0,0,0,0,0,0,1) to integer (integer varible = 10000001 not 129)
You basiclly have the answer but you would be better doing it from the other direction ie:
int multiplier = 1;
for (i = 7; i >= 0; --i )
{
bin += (multiplier * arrbin[i]);
multiplier *= 10;
}
that way you can change the length of the array you are using easily.
How about do it manually, the same way you do it to convert binary to int using powers of 2
#include <stdio.h>
#include <string.h>
main()
{
int arr[4]={1,0,0,1};
int i;
int output=0, power=1;
for (i=0; i<4; i++)
{
output += arr[3-i]*power;
power *= 2;
}
printf("%d\n", output);
in this example
arr = 1 0 0 1
output = 1*2^0 + 0*2^1 + 0*2^2 + 1*2^3 = 9
You're forgetting that binary doesn't work by multiplying the value by 10, but by 2 (multiplying by 10 would be good it you're converting a decimal number to an int, but there are already functions for that).
So if I take your code and apply the appropriate multiplication:
for (bin = 0, i = 0; i < 8; ++i )
{
bin *= 2;
bin = bin + arrbin[i];
}
Instead of multiplying by 2 the value of bin, you can use bitshifts instead (replace bin *= 2; with bin = bin << 1;).
All this supposes that the arrbin array contains valid values, and not, for example, ASCII characters of the values. If this is the case, you will have to convert it to a valld value before adding it to bin.
I had to use this method to convert my binary array to a decimal integer. These other solutions didn't work for me, perhaps my array wasn't setup the same but either way, here is my answer to this question.
int bin_to_int_digit(int* in, int length)
{
int exp = 0;
int i;
int bin = 0;
for (i = length - 1; i >= 0; i--)
{
bin += in[i] * pow(2, exp);
exp += 1;
}
return bin;
}
This subroutine requires the use of the math.h header so make sure you include -lm flag when compiling with gcc or else you will get an error.

Program crashes when `if (variable % 2 == 0)`

I'm writing a program that finds perfect numbers. Having read about these perfect numbers I came across a list of them: List of perfect numbers. At the moment the output is:
28 // perfect
496 // perfect
8128 // perfect
130816 // not perfect
2096128 // not perfect
33550336 // perfect
I decided to create array and put it with numbers, which divide the number wholly (without the rest). So I will be able to verify if it is a perfect number or not by adding all elements of the array. But app crashes and I cannot understand why:
#include <stdio.h>
#include <stdlib.h>
int main()
{
unsigned long number;
unsigned long arr2[100] = {0};
int k = 0;
for ( number = 0; number <= 130816; number++ )
if ( 130816 % number == 0 )
arr2[k++] = number;
for ( k = 0; k < 100; k++ )
printf("%lu", arr2[k]);
return 0;
}
You are doing modulus zero here:
if ( 130816 % number == 0 )
which is undefined behavior. If you start your for loop at 1 instead it should fix that issue. However, since N % 1 == 0 for all N, you probably need to start at 2.
From the C99 standard, 6.5.5 /5 (unchanged in C11):
The result of the / operator is the quotient from the division of the first operand by the
second; the result of the % operator is the remainder. In both operations, if the value of
the second operand is zero, the behavior is undefined.
You are dividing by zero when number=0;
138816 % number involves division and a remainder.

Resources