c program for binary to decimal conversion [closed] - c

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Questions concerning problems with code you've written must describe the specific problem — and include valid code to reproduce it — in the question itself. See SSCCE.org for guidance.
Closed 9 years ago.
Improve this question
Please help me to sort out the error in the following program.I am not getting the correct output for the decimal part.
Thanks in advance
#include<stdio.h>
#include<math.h>
main()
{
int p,i,j,t,x;
float n,sum,d;
printf("enter the binary number");
scanf("%f",&n);
p=(int)n;
d=n-p;
i=0;
while(p>0)
{
t=p%10;
sum=sum+t*pow(2,i);
p=p/10;
i=i+1;
}
i=1;
while(d>0.0)
{
d=d*10;
x=(int)d;
sum=sum+x*pow(2,-i);
d=d-x;
i=i+1;
}
printf("decimal value is %f",sum);
getch();
}

You're problem is that you're using float when you should be using int and you haven't initialized any of your variables. Change float to int and initialize your variables to 0 and your code will work.
The reason your code isn't working is because sum isn't initialized. When you use sum = sum + t * pow (2, i), you are adding an arbitrary number to the result in the first go around. sum could be anything before it's initialized (ie -1241232).
Even though the only variables that really need to be initialized are sum, d, and i, it's a good practice to initialize them anyway (better safe than sorry). In fact, initialized variables are a very common cause of errors. Initialize everything.
The floating point datatype is also causing problems in you code, in the second loop. When the user inputs a floating point number, like 110.1101, it gets approximated to another number (ie 110.110098) - this has to do with the limitation of the floating point datatype.
In your second loop, with the input approximated to 110.1100998, the problem is caused in this statement:
sum = sum + x * pow (2.0f, -i);
Because x isn't 1 or 0 throughout the whole loop (sometimes 9 or 8, etc). What's more, the loop doesn't just iterate 4 times (1101), it does many more. This is because of this statement:
d = d * 10;
When d gets multiplied by 10, it goes from 0.100998 to about 1.00979 - not 1.00998
like you'd expect. These two discrepancies are what's causing your results to be erroneous when you input values more precise than a single digit.
Finally, here's some working code:
#include <stdio.h>
#include <math.h>
int main (){
int p = 0, i = 0, j = 0, t = 0, x = 0;
float n = 0.0f, sum = 0.0f, d = 0.0f;
printf("enter the binary number: ");
scanf("%f", &n);
p = n;
d = n - p;
while (p > 0){ // never use the float datatype for iteration
t = p % 10;
sum = sum + t * pow (2.0f,i);
p = p / 10;
i = i + 1;
}
i = 1;
while (d > 0.00001){
d = d * 10;
x = d;
sum = sum + x * pow (2.0f, -i);
d = d - x;
i = i + 1;
}
printf ("decimal value is %f\n", sum);
getchar ();
return 0;
}

I am assuming you are expecting input of the form [01.]* with the constraint that there is only one decimal point. You are reading this input like a regular floating point number, but interpreting its decimal digits as binary digits and computing the decimal value.
main() should be declared int main (). getch() isn't a standard C call. You can use getchar().
You are probably getting crazy output because sum is not initialized to 0.
When you compute your fractional terms, you have to keep in mind that floating point representation is binary, and not all decimal numbers have an exact representation. So you need to perform rounding. Also, you are checking for d>0 as your stopping condition for your second loop, but floating point comparison is trickier than that. You can read this answer for a complete explanation as to why it is tricky, but you should basically do something like this:
float err=.000001;
while(d>err)
{
d=d*10;
err=err*10;
x=(int)(d+.5);
/*...*/
The floating point complexity of your code can be reduced by reading your input as a string, and parsing that instead.
char *n;
char p[INPUT_MAX];
char d[INPUT_MAX];
char input[INPUT_MAX];
float sum, p_sum = 0, d_sum = 0;
int i;
printf("enter the binary number: ");
if (fgets(input, sizeof(input), stdin) == 0) {
puts("no input!");
exit(0);
}
n = strchr(input, '.');
if (sscanf(input, "%[01]", p) == 1) {
for (i = 0; p[i] != '\0'; ++i) {
p_sum = 2*p_sum + (p[i] - '0');
}
}
if (sscanf(n, ".%[01]", d) == 1) {
for (i = strlen(d); i > 0; --i) {
d_sum = (d_sum + (d[i-1] - '0'))/2;
}
}
sum = p_sum + d_sum;
printf("decimal value is %f\n",sum);

Related

How do I alternate the sign of a summation series

I am trying to code the summation of the following series:
I can't figure out how to alternate the sign from "-" to "+" to "-" and so on....
Here is my code:
#include<stdio.h>
int main()
{
int i=1,n;
float sum,num,den;
den=2;
sum=0;
printf("Enter number of terms for summation: ");
scanf("%d",&n);
for(i=1;i<=n;i++)
{
num=i*(i+1);
den=den*(i+2);
sum+=num/den;
}
printf("%f",sum);
}
Start a variable at 1.
int coeff = +1;
then:
sum += coeff * num/den;
coeff *= -1; // Toggles -1 to +1 and back to -1 each loop.
When coeff is +1, then the expression is +1 * -1, which results in -1.
When coeff is -1, then the expression is -1 * -1, which results in +1.
the variable keeps toggling back-n-forth between +1 and -1.
Let’s discuss the methods proposed in comments and other answers in descending order of nominal burden. (By “nominal burden,” I meant what the code literally says to calculate, disregarding potential compiler optimization.)
sum+=pow(-1,i)*num/den. This calls pow, which is a complicated routine. This solution involves a function call and branching through the various special cases that pow must handle.
if ((i & 1) == 0) num = -num;. This involves testing, comparing, branching, negating, and assignment. For hardware design reasons, branching may impair performance.
int coeff = +1;, sum += coeff * num/den;, and coeff *= -1;. Okay, now we are on track. We have added just one variable and two multiplications. The latter does not even have to be a multiplication; it could be just coeff = -coeff;.
Having learned from those, can we solve it any more simply? Yes, we make a simple change, from:
den=den*(i+2);
to:
den=-den*(i+2);
Then den will flip between positive and negative each iteration, with just a single negation. However, we do need to start den with a negative value; den = -2;.
But then, consider this:
den = den*(-2-i);
Although this involves more characters changed in the source code, it might not be any more work. i+2 may be calculated by taking 2 and adding i, whereas -2-i may be calculated by taking −2 and subtracting i, the same amount of work.
Thus, you can make your program work for alternating signs without any more nominal work than the unchanging sign version.
int main()
{
int i=1,n, sign = 1;
float sum,num,den;
den=2;
sum=0;
printf("Enter number of terms for summation: ");
scanf("%d",&n);
for(i=1;i<=n;i++)
{
num=i*(i+1);
den=den*(i+2);
sum+=sign * num/den;
sign *= -1;
}
printf("%f",sum);
}
With x = i % 2 alternating between 0 and 1, you have two equations in two variables:
+1 = A * 0 + B
-1 = A * 1 + B
From which you can quickly infer:
B = 1
A = -2
So what you can do is:
const int A = -2;
const int B = 1;
...
for (i = 0; i < n; i++)
{
int x = i % 2;
int y = A * x + B;
...
sum+=y*num/den;
}

How to reduce this piece of code in order to avoid TLE

The program is to find the number of digits in a factorial of a number
#include <stdio.h>
#include <math.h>
int main()
{
int n = 0 , i , count = 0 , dig ;
double sum = 0, fact;
scanf("%d" , &n );
for(i=1;i<=n;i++)
{
sum = sum + log(i);
}
fact = (exp(sum));
while(fact!=0)
{
dig = ((int)fact%10);
count++;
fact = floor(fact/10);
}
printf("%d\n",count);
return 0;
}
Feel free to comment on making improvements on this code since I don't have a broad experience in Coding yet.
The reason your code is taking so long is that once n reaches about 180, the value of fact becomes too large to hold in a double-precision floating point variable. When you execute this line:
fact = (exp(sum));
you're basically setting fact to a value of infinity. As a result, the following while() loop never terminates.
There's also not much point calculating logarithms in your code. It will only slow things down. Just calculate the factorial in a double variable and reset it whenever it gets too large. Like this, for example:
int factorial_digit_count(int n) {
int i, nd=1;
double f = 1.0;
for (i=2; i<=n; i++) {
f *= i;
if (f > 1.0E+100) {
f /= 1.0E+100;
nd += 100;
}
}
while (f > 1.0E+10) {
f /= 1.0E+10;
nd += 10;
}
while (f >= 10.0) {
f /= 10.0;
nd++;
}
return nd;
}
Assuming you don't want to use any mathematical calculation but want to "brute force" your way through - this would how I would shorten your run time (and mostly clean up you code).
#include <stdio.h>
#include <math.h>
int main()
{
int n, fact = 1;
scanf("%d" , &n );
for (int i = 1; i < n; i++)
fact *= i;
int sum = 0;
while (fact != 0)
{
fact /= 10;
sum++
}
printf("%d\n",count);
return 0;
}
Hopefully this answers your question, good luck!
There is a simple relationship between the base b logarithm of a number and the base b representation of that number:
len(repr(x, b)) = 1 + floor(log(x, b))
In particular, in base 10, the number of digits in x is 1 + floor(log10(x)). (To see why that's the case, look at the result of that formula for powers of 10.)
Now, the logarithm of a×b is the sum of the logarithms of a and b. So the logarithm of n! is simply the sum of the logarithms of the integers from 1 to n. If we do that computation in base 10, then we can easily extract the length of the decimal expansion of n!.
In other words, if you sum the log10 of each value instead of the log, then you can get rid of:
fact = (exp(sum));
and
while(fact!=0)
{
dig = ((int)fact%10);
count++;
fact = floor(fact/10);
}
and just output 1 + floor(sum).
In theory, that could suffer from a round-off error. However, you'd need to do an awful lot of logarithms in order for the error term to propagate enough to create an error in the computation. (Not to say it can't happen. But if it happens, n is a very big number indeed.)

Decompose decimal part of a double

I need to decompose a decimal part of a number in single digits, but I need to get the most obvious representation. Here is my code, to be clearer :
#include <stdio.h>
void main(){
double value = 0.123;
int decim_tab[6];
int decimal;
int i;
for (i = 0; i < 6; ++i) {
value *= 10;
decimal = (int)value;
decim_tab[i] = decimal;
value -= decimal;
}
for (i = 0; i < 6; ++i)
print("%d\n", decim_tab[i]);
}
The output I need is :
1
2
3
0
0
0
But I get :
1
2
2
9
9
9
EDIT
A solution I found is to add a small delta to the value in order to force the shortest representation :
#include <stdio.h>
void main(){
double value = 0.123;
int decim_tab[6];
int decimal;
int i;
value += 0.000000001
for (i = 0; i < 6; ++i) {
value *= 10;
decimal = (int)value;
decim_tab[i] = decimal;
value -= decimal;
}
for (i = 0; i < 6; ++i)
print("%d\n", decim_tab[i]);
}
I would be happy to find a better way, any suggestions ?
The reason you get unexpected output is that decimal fractions cannot always be exactly represented using (most common) base two floating point numbers. Using printf("%.20f", value); after your assignment of value you will see that the value 0.123 is actually being stored as 0.12299..., which is why you receive that output.
If you only need to print out six digits, you can use string formatting of floating point numbers:
#include <stdio.h>
#include <stdlib.h>
int main(){
double value = 0.123;
char *s = malloc(9);
sprintf(s++, "%.6f", value);
while(*s++){
putchar(*s);
putchar('\n');
}
}
EDIT: The code in my answer is very specific to the example you gave, so when using it be aware that I made some assumptions, e.g. your value will never have more than one digit before the decimal point.
If you want 6 decimal places, you should add 0.0000005 (ie 0.5e-6) to round the value to the nearest place. This method will work for positive numbers, first extract the sign, then work on the absolute value.
Floating point numbers are not exact value representation. Here's a simple sample:
double a = 0.15 + 0.15; // 0.15 + 0.15 == 0.3, right?
double b = 0.1 + 0.2; // 0.1 + 0.2 == 0.3, right?
if (a == b) {
printf("Equal\n");
} else {
printf("Unequal\n");
}
What will that print? Equal? Are you sure? Try it yourself:
http://rextester.com/VZOZ1043
It prints Unequal, that's because there are some numbers that floating point can't represent exactly and that's something you always need to keep in mind when doing floating point math. Also there is rounding involved in many operations, so the results of math operations are as good as possible but not always "exact", there's a tiny error that can also sum up if you run multiple operations.
double value = 0.123;
// Assuming none of your numbers has more than 58 digits,
// one period and one termination char.
char buffer[60];
// Print the number to the buffer.
// Missing: Error checking if it did fit!
snprintf(buffer, sizeof(buffer), "%f", value);
// Find the period or end of string
int idx = 0;
for (; buffer[idx] && buffer[idx] != '.'; idx++);
// Print anything after the period till
// the end of the string
if (buffer[idx] == '.') {
for (idx++; buffer[idx]; idx++) {
printf("%c\n", buffer[idx]);
}
}
Test it: http://rextester.com/CYDQO24769

|c| Series 1+2x+3x^2+4x^3+....nx^(n-1)

First of all, I searched and all questions I found are similar but not exactly this one.
This is my first post here, I'm a beginner in programming and currently learning to code in C.
Been struggling with this code for about 5 hours now.
The question is create a program in C, using only loops (and not using pow(), using stdio.h library only).
The question is to get the user to give you two numbers - X and N
the program will print The result of the following equation:
1+2x+3x^2+4x^3+....+nx^(n-1)
For example for the input of - X=2 N=3
1*2^0 + 2*2^1 + 3*2^2
What the program will print is "17"
This is my attempt so far, I got to the Power function but I cant find a way to incorporate into the programm itself.
#include <stdio.h>
int main(void)
{
int i, j=0, b = 0;
float x, n;
double sum = 0, sumt=0;
do{
printf("Please enter two numbers \n");
flushall;
scanf("%f %f", &n, &x);
} while (x <= 0);
for (i = 1; i <= n; i++){
sum = x*x;
}
sumt += sum;
printf("%f", sum);
}
Instead of trying to create an implementation of pow, you will need to take advantage of the relationship between the terms of the expression.
The n-th term is nx^(n-1). The n-1-the term is (n-1)x^(n-2).
If we denote the n-th term as T(n) and denote the n-1-th term as T(n-1),
T(n) = T(n-1)*x*n/(n-1)
Given the starting value of the first term,
T(1) = 1
you can compute the subsequent terms using the above formula.
The following code should work.
// Initialize the values for N=1
term = 1;
sum = 1;
// Iterate starting from 2
for (i = 2; i <= n; i++){
term *= x*i/(i-1);
sum += term;
}
The working Program based on the tips given by the almighty #R_Sahu (And others ;D)
**
#include <stdio.h>
int main(void)
{
int i, j = 0, c = 0;
float x, n, b = 0;
double term, sum;
do {
printf("Enter Two Numbers\n");
flushall;
scanf("%f%f", &n, &x);
} while (x < 0);
for (i = 2; i < n + 2; i++)
{
term = 1;
sum = 1;
for (i = 2; i <= n; i++){
term *= x*i / (i - 1);
sum += term;
}
}
printf("The answer is %.lf ", sum);
}
I will not give you the code, but the reasoning you should follow
First you have to somehow get the data from the user (as a parameter, from stdio... whatever)
x = getFromUser
n = getFromUser
You will then need to init a temporary result
result = 0
How many times do you have to add? -> Exactly n times
for(ii=0;ii<n;ii++) {
result = result + pow((ii*x),(ii-1)) //There is something missing here, I'll let you guess what
}
But wait; you cannot use pow. So you have to program it by yourself (I guess that's the idea of the exercise)
then you need a function, and it has to return an int (actually, it may return even irrational numbers, but I don't think they will require you to do that)
int customPow(int base, int exponent) {
//Put your for in here, and may the pow be with you
}
You need to figure out the code yourself, but the general idea is as follows:
Create your own pow function which returns x*n.
int pow(int x, int n){
//use a for or while loop to calculate x (*x)n times.
//pay attention to the base cases (i.e., when n = 0, or 1 etc)
}
ans = 0;
for(i = 0 to N-1){
ans = ans + pow(x,i-1)*i;
}

Multiplication of very large numbers using character strings

I'm trying to write a C program which performs multiplication of two numbers without directly using the multiplication operator, and it should take into account numbers which are sufficiently large so that even the usual addition of these two numbers cannot be performed by direct addition.
I was motivated for this when I was trying to (and successfully did) write a C program which performs addition using character strings, I did the following:
#include<stdio.h>
#define N 100000
#include<string.h>
void pushelts(char X[], int n){
int i, j;
for (j = 0; j < n; j++){
for (i = strlen(X); i >= 0; i--){
X[i + 1] = X[i];
}
X[0] = '0';
}
}
int max(int a, int b){
if (a > b){ return a; }
return b;
}
void main(){
char E[N], F[N]; int C[N]; int i, j, a, b, c, d = 0, e;
printf("Enter the first number: ");
gets_s(E);
printf("\nEnter the second number: ");
gets_s(F);
a = strlen(E); b = strlen(F); c = max(a, b);
pushelts(E, c - a); pushelts(F, c - b);
for (i = c - 1; i >= 0; i--){
e = d + E[i] + F[i] - 2*'0';
C[i] = e % 10; d = e / 10;
}
printf("\nThe answer is: ");
for (i = 0; i < c; i++){
printf("%d", C[i]);
}
getchar();
}
It can add any two numbers with "N" digits. Now, how would I use this to perform multiplication of large numbers? First, I wrote a function which performs the multiplication of number, which is to be entered as a string of characters, by a digit n (i.e. 0 <= n <= 9). It's easy to see how such a function is written; I'll call it (*). Now the main purpose is to multiply two numbers (entered as a string of characters) with each other. We might look at the second number with k digits (assuming it's a1a2.....ak) as:
a1a2...ak = a1 x 10^(k - 1) + a2 x 10^(k - 2) + ... + ak-1 x 10 + ak
So the multiplication of the two numbers can be achieved using the solution designed for addition and the function (*).
If the first number is x1x2.....xn and the second one is y1y2....yk, then:
x1x2...xn x y1y2...yk = (x1x2...xn) x y1 x 10^(k-1) + .....
Now the function (*) can multiply (x1x2...xn) with y1 and the multiplication by 10^(k-1) is just adding k-1 zero's next to the number; finally we add all of these k terms with each other to obtain the result. But the difficulty lies in just knowing how many digits each number contains in order to perform the addition each time inside the loop designed for adding them together. I have thought about doing a null array and each time adding to it the obtained result from multiplication of (x1x2....xn) by yi x 10^(i-1), but like I've said I am incapable of precising the required bounds and I don't know how many zeros I should each time add in front of each obtained result in order to add it using the above algorithm to the null array. More difficulty arises when I'll have to do several conversions from char types into int types and conversely. Maybe I'm making this more complicated than it should; I don't know if there's an easier way to do this or if there are tools I'm unaware of. I'm a beginner at programming and I don't know further than the elementary tools.
Does anyone have a solution or an idea or an algorithm to present? Thanks.
There is an algorithm for this which I developed when doing Small Factorials problem on SPOJ.
This algorithm is based on the elementary school multiplication method. In school days we learn multiplication of two numbers by multiplying each digit of the first number with the last digit of the second number. Then multiplying each digit of the first number with second last digit of the second number and so on as follows:
1234
x 56
------------
7404
+6170- // - is denoting the left shift
------------
69104
What actually is happening:
num1 = 1234, num2 = 56, left_shift = 0;
char_array[] = all digits in num1
result_array[]
while(num2)
n = num2%10
num2 /= 10
carry = 0, i = left_shift, j = 0
while(char_array[j])
i. partial_result = char_array[j]*n + carry
ii. partial_result += result_array[i]
iii. result_array[i++] = partial_result%10
iv. carry = partial_result/10
left_shift++
Print the result_array in reverse order.
You should note that the above algorithm work if num1 and num2 do not exceed the range of its data type. If you want more generic program, then you have to read both numbers in char arrays. Logic will be the same. Declare num1 and num2 as char array. See the implementation:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(void)
{
char num1[200], num2[200];
char result_arr[400] = {'\0'};
int left_shift = 0;
fgets(num1, 200, stdin);
fgets(num2, 200, stdin);
size_t n1 = strlen(num1);
size_t n2 = strlen(num2);
for(size_t i = n2-2; i >= 0; i--)
{
int carry = 0, k = left_shift;
for(size_t j = n1-2; j >= 0; j--)
{
int partial_result = (num1[j] - '0')*(num2[i] - '0') + carry;
if(result_arr[k])
partial_result += result_arr[k] - '0';
result_arr[k++] = partial_result%10 + '0';
carry = partial_result/10;
}
if(carry > 0)
result_arr[k] = carry +'0';
left_shift++;
}
//printf("%s\n", result_arr);
size_t len = strlen(result_arr);
for(size_t i = len-1; i >= 0; i-- )
printf("%c", result_arr[i]);
printf("\n");
}
This is not a standard algorithm but I hope this will help.
Bignum arithmetic is hard to implement efficiently. The algorithms are quite hard to understand (and efficient algorithms are better than the naive one you are trying to implement), and you could find several books on them.
I would suggest using an existing Bignum library like GMPLib or use some language providing bignums natively (e.g. Common Lisp with SBCL)
You could re-use your character-string-addition code as follows (using user300234's example of 384 x 56):
Set result="0" /* using your character-string representation */
repeat:
Set N = ones_digit_of_multiplier /* 6 in this case */
for (i = 0; i < N; ++i)
result += multiplicand /* using your addition algorithm */
Append "0" to multiplicand /* multiply it by 10 --> 3840 */
Chop off the bottom digit of multiplier /* divide it by 10 --> 5 */
Repeat if multiplier != 0.

Resources