I'm trying to build a calculator, which input a number n it can automatically output the sum of
1/2+2/2 +1/3+2/3+3/3 +...+1/n+2/n+...+n/n and for each denominator, print the result once.
The calculator will restart and ask for input after output the final result of 1/2+2/2 +1/3+2/3+3/3 +...+1/n+2/n+...+n/n .And when the the user decides to stop the program enter 0.
for input=3 ,the output is sum =1 ,sum=2 ,yet I expected it to be sum=3/2, sum=7/2
Here's the program
#include <stdio.h>
int main(){
printf("Please enter the max denominator:\n");
int i,j,n;
int sum=0;
do{
scanf("%d",&n);
for (j=2;j<=n;j++){
for(i=1;i<=j;i++){
sum+= i/j;
if (i==j){
printf("sum=%d\n",sum);
break;
}
}
}
} while (n!=0);
return 0;
}
EDIT: revised part due to advice
int i,j,n;
double sum=0.0;
do{
scanf("%d",&n);
sum=0.0;
for (j=2;j<=n;j++){
for(i=1;i<=j;i++)
sum+=(double)i/j;
printf("sum=%lf\n",sum);
}
} while (n!=0);
return 0;
}
Your program is working with integers. i, j, n, and sum are all integers. This means they cannot encode numbers like 3/2 or 7/2.
So what happens when you divide two integers, like 1/2? The answer is that the result rounds down to the nearest integer. Since 1/2 is 0.5, the nearest integer below that is 0, so the result is 0.
You need to use float, which uses floating point arithmetic. Floating point arithmetic has its own set of fun rounding issues (You may be surprised to find that "0.2" cannot be represented exactly with floating point numbers).
A more exact alternative is to write your own functions to handle rational numbers as a pair of integers -- a numerator and a denominator. It will require additional algorithms (such as a Greatest Common Divisor algorithm), but it can describe these sorts of problems exactly.
Related
I am trying to write a program that outputs the number of the digits in the decimal portion of a given number (0.128).
I made the following program:
#include <stdio.h>
#include <math.h>
int main(){
float result = 0;
int count = 0;
int exp = 0;
for(exp = 0; int(1+result) % 10 != 0; exp++)
{
result = 0.128 * pow(10, exp);
count++;
}
printf("%d \n", count);
printf("%f \n", result);
return 0;
}
What I had in mind was that exp keeps being incremented until int(1+result) % 10 outputs 0. So for example when result = 0.128 * pow(10,4) = 1280, result mod 10 (int(1+result) % 10) will output 0 and the loop will stop.
I know that on a bigger scale this method is still inefficient since if result was a given input like 1.1208 the program would basically stop at one digit short of the desired value; however, I am trying to first find out the reason why I'm facing the current issue.
My Issue: The loop won't just stop at 1280; it keeps looping until its value reaches 128000000.000000.
Here is the output when I run the program:
10
128000000.000000
Apologies if my description is vague, any given help is very much appreciated.
I am trying to write a program that outputs the number of the digits in the decimal portion of a given number (0.128).
This task is basically impossible, because on a conventional (binary) machine the goal is not meaningful.
If I write
float f = 0.128;
printf("%f\n", f);
I see
0.128000
and I might conclude that 0.128 has three digits. (Never mind about the three 0's.)
But if I then write
printf("%.15f\n", f);
I see
0.128000006079674
Wait a minute! What's going on? Now how many digits does it have?
It's customary to say that floating-point numbers are "not accurate" or that they suffer from "roundoff error". But in fact, floating-point numbers are, in their own way, perfectly accurate — it's just that they're accurate in base two, not the base 10 we're used to thinking about.
The surprising fact is that most decimal (base 10) fractions do not exist as finite binary fractions. This is similar to the way that the number 1/3 does not even exist as a finite decimal fraction. You can approximate 1/3 as 0.333 or 0.3333333333 or 0.33333333333333333333, but without an infinite number of 3's it's only an approximation. Similarly, you can approximate 1/10 in base 2 as 0b0.00011 or 0b0.000110011 or 0b0.000110011001100110011001100110011, but without an infinite number of 0011's it, too, is only an approximation. (That last rendition, with 33 bits past the binary point, works out to about 0.0999999999767.)
And it's the same with most decimal fractions you can think of, including 0.128. So when I wrote
float f = 0.128;
what I actually got in f was the binary number 0b0.00100000110001001001101111, which in decimal is exactly 0.12800000607967376708984375.
Once a number has been stored as a float (or a double, for that matter) it is what it is: there is no way to rediscover that it was initially initialized from a "nice, round" decimal fraction like 0.128. And if you try to "count the number of decimal digits", and if your code does a really precise job, you're liable to get an answer of 26 (that is, corresponding to the digits "12800000607967376708984375"), not 3.
P.S. If you were working with computer hardware that implemented decimal floating point, this problem's goal would be meaningful, possible, and tractable. And implementations of decimal floating point do exist. But the ordinary float and double values any of is likely to use on any of today's common, mass-market computers are invariably going to be binary (specifically, conforming to IEEE-754).
P.P.S. Above I wrote, "what I actually got in f was the binary number 0b0.00100000110001001001101111". And if you count the number of significant bits there — 100000110001001001101111 — you get 24, which is no coincidence at all. You can read at single precision floating-point format that the significand portion of a float has 24 bits (with 23 explicitly stored), and here, you're seeing that in action.
float vs. code
A binary float cannot encode 0.128 exactly as it is not a dyadic rational.
Instead, it takes on a nearby value: 0.12800000607967376708984375. 26 digits.
Rounding errors
OP's approach incurs rounding errors in result = 0.128 * pow(10, exp);.
Extended math needed
The goal is difficult. Example: FLT_TRUE_MIN takes about 149 digits.
We could use double or long double to get us somewhat there.
Simply multiply the fraction by 10.0 in each step.
d *= 10.0; still incurs rounding errors, but less so than OP's approach.
#include <stdio.h>
#include <math.h> int main(){
int count = 0;
float f = 0.128f;
double d = f - trunc(f);
printf("%.30f\n", d);
while (d) {
d *= 10.0;
double ipart = trunc(d);
printf("%.0f", ipart);
d -= ipart;
count++;
}
printf("\n");
printf("%d \n", count);
return 0;
}
Output
0.128000006079673767089843750000
12800000607967376708984375
26
Usefulness
Typically, past FLT_DECMAL_DIG (9) or so significant decimal places, OP’s goal is usually not that useful.
As others have said, the number of decimal digits is meaningless when using binary floating-point.
But you also have a flawed termination condition. The loop test is (int)(1+result) % 10 != 0 meaning that it will stop whenever we reach an integer whose last digit is 9.
That means that 0.9, 0.99 and 0.9999 all give a result of 2.
We also lose precision by truncating the double value we start with by storing into a float.
The most useful thing we could do is terminate when the remaining fractional part is less than the precision of the type used.
Suggested working code:
#include <math.h>
#include <float.h>
#include <stdio.h>
int main(void)
{
double val = 0.128;
double prec = DBL_EPSILON;
double result;
int count = 0;
while (fabs(modf(val, &result)) > prec) {
++count;
val *= 10;
prec *= 10;
}
printf("%d digit(s): %0*.0f\n", count, count, result);
}
Results:
3 digit(s): 128
This is a code that I wrote to find the cube root of a number using Newton Raphson. However, it always shows the answer as -1#IND0. Can you help me find what is wrong with this code?
#include <stdio.h>
int main()
{
float x_0,x,x_m,n;
int m,i=0;
printf("Enter integer you wish to find the cube root of: ");
scanf("%f",&n);
printf("\nEnter your first guess and number of steps: ");
scanf("%f %d",&x_0,&m);
x_m=(1/3)*((2*x_0)+(n/(x_0*x_0)));
// printf("\nx_m=%f\nx_0=%f\nm=%d",x_m,x_0,m);
while( i<m)
{
x=x_m;
x_m=(1/3)*((2*x)+(n/(x*x)));
i++;
}
printf("\nThe cube root of %.0f is approximately %.5f",n,x_m);
return 0;
}
Before the loop starts, m_x will be zero since (1/3) is zero (integer division).
On the first iteration, (n/(x*x)) is then a poll as x will be zero. That accounts for the output being -1#IND0.
The fix, as always, is to remove all those extra parentheses that folk always seem to put in:
x_m=(2*x + n/(x*x))/3;
&c. (although your duplication of the Newton Raphson formula is unsatisfactory - as you have to put the fix in two places.). Because x is a floating point type, all the arithmetic will be performed in floating point, due to the sensible rules of type promotion.
After you've fixed this, bin it and use cbrt, from the C standard library header math.h.
Before the while you have
x_m=(1/3)*((2*x_0)+(n/(x_0*x_0)));
Since 1/3 will yield 0, x_m will be 0. And then you have
x_m=(1/3)*((2*x)+(n/(x*x)));
where you use x*x as a quantity to divide n with. Since x is 0, the result will have an undefined behavior. Try to make sure the amount you divide with is not 0, but a valid value, start with (1.0/3).
So I am trying to write a program which takes a floating point value and represents it in terms of a fraction. I am facing a weird problem. This is my program:
#include<stdio.h>
#include<math.h>
int gcd(int,int);
void main()
{
int n,n1,n2,g;
float a,a1;
printf("Enter number of digits after decimal point: ");
scanf("%d",&n);
printf("Enter number: ");
scanf("%f",&a);
n2=pow(10,n);
a1=a*n2;
n1=(int)a1;
g=gcd(n1,n2);
n1/=g;n2/=g;
printf("The number is %d/%d",n1,n2);
}
int gcd(int a,int b)
{
int x,flag=0;
int n1=((a>b)?a:b);
int n2=((a<b)?a:b);
for(x=n1;x>=1;x--)
{
if(n1%x==0 && n2%x==0)
{
flag=1;break;
}
}
if(flag==1)
return x;
else
return 1;
}
Now this program gives the correct answer for numbers with only 1 decimal point. For example:
Enter number of digits after decimal point: 1
Enter number: 2.5
The number is 5/2
However for number with two or more digits after decimal point it gives a wrong answer. For example:
Enter number of digits after decimal point: 2
Enter number: 2.50
The number is 247/99
I know that floating point numbers are not accurate but I did not expect this big a variation. Is there any way to work around this and make this program work???
Works for me. I believe the reason is that you use pow(10, n) and pow is inexact on your platform. Use a simple for-loop instead:
n2 = 1;
for (int c = 0; c < n; c++) {
n2 *= 10;
}
As functions like pow(10, n) may generate results near an integer value instead of an exact integer value. Rather than truncating with (int), use one of the round functions should you want to continue using pow().
Consider long int lround(double x), long int lroundf(float x) which round and covert to an integer type in one call.
The lround and llround functions round their argument to the nearest integer value, rounding halfway cases away from zero, regardless of the current rounding direction. C11 §7.12.9.7 2
n2 = lround(pow(10,n));
a1 = a*n2;
n1 = lroundf(a1);
my program reads data from that file :
6 150
0 1.75
30 0.8
60 0.5
70 1
120 0.1
140 0.9
and inserts those numbers(It starts from the second row) into an array of structs and then calculates the 'time'. The results are fine but one; the third one('time') is 100 but the output is 99.999992.
Here is the program :
#include <stdio.h>
#include <stdlib.h>
int di,i,k,m;
float vi,time;
int n;
int l;
struct node
{
int distance;
float velocity;
}DV[500000];
struct timeslist_node
{
struct timeslist_node *left;
int winner;
int loser;
double time;
struct timelist_node *right;
};
double calctime(int d,float v);
void print_array();
main()
{
FILE *fp;
fp=fopen("candidates.txt","r");
if (fp==NULL) exit(2);
fscanf(fp,"%d %d",&n,&l);
printf("%d,%d\n",n,l);
for(i=0;i<n;i++)
{
fscanf(fp,"%d %f",&DV[i].distance,&DV[i].velocity);
}
calctime(DV[i].distance,DV[i].velocity);
print_array();
fclose(fp);
system("pause");
}
double calctime(int d,float v)
{
for(i=0;i<n;i++)
{
if (i == 0)
{
{
if (DV[n-1].velocity==DV[i].velocity)
time=-1;
}
time=((l-DV[n-1].distance)/(DV[n-1].velocity-DV[i].velocity));
m=1;
k=n;
}
else
{
{ if (DV[i-1].velocity==DV[i].velocity)
time=-1;
}
time=((DV[i].distance-DV[i-1].distance)/(DV[i-1].velocity-DV[i].velocity));
k=i;
m=i+1;
}
printf ("t %d %d=%lf\n",m,k,time);
}
}
void print_array()
{
for(i=0;i<n;i++)
printf("D[%d],V[%d] = %d %.2f\n ",i,i,DV[i].distance,DV[i].velocity );
}
Thats happens because floating point numbers have a limited precision. If you want to know why, have a deeper look at how floating point are stored in the memory. http://en.m.wikipedia.org/wiki/Floating_point.
Typical float will handle math as expected, but only to within a certain range and precision.
That precision is typically about 6, maybe 7, significant digits. See FLT_DIG in <float.h>. 99.999992 is the results of printing a number to 8 significant digits. Using printf("%.5e", some_float) will limit the output to its realistic precision.
Using double rather than float will typically provide additional range and precision. But the same issues occur, albeit with more extreme numbers.
As many other have said, there are many issues contributing to the the fact that the sum was printed as 99.999992 rather than 100.0.
First, the sum is most likely precisely 99.99999237060546875, which is the previous float, assuming binary32, to 100.0. Printing a number like 99.99999237060546875 to 8 significant places is moving beyond reasonable precision expectations of float in C. "%f" prints a number with 6 digits following the decimal point. Since the number was 99.99999237060546875, a rounded number of 99.999992 with 2 + 6 significant digits was printed.
2nd: various math operations have inexact results. This is expected with 1.0/3.0, but it also happens with 100 + 0.1. This idea is outlined in the classic reference What Every Computer Scientist Should Know About Floating-Point Arithmetic
3rd, recall floating point numbers are not linearly, but logarithmically distributed. There are about as many numbers between 1.0 and 10.0 as between 10.0 and 100.0.
Can't you use Round for this?
Round(*STRING*);
Source: http://msdn.microsoft.com/en-us/library/75ks3aby(v=vs.110).aspx
I have to write a program which calculates and displays the following expression:
P=(1/2-3/4)*(5/6-7/8)*...*[n/(n-1) - (n+2)/(n+3)]
I did this and I ran it and it shows no errors. When I run it, for every value that I enter, it shows P=0. What is wrong?
#include <stdio.h>
int main (void)
{
float s, p=1.0;
int i, n;
printf("Enter a number:");
scanf("%d", &n);
for (i=1;i<=n;++i) {
p*=((i)/(i+1)-(i+2)/(i+3));
}
printf("p=%f\n", p);
}
You're using integer arithmetic rather than floating point, so the division operations are being truncated.
Change:
p*=((i)/(i+1)-(i+2)/(i+3));
to:
p*=((float)(i)/(i+1)-(float)(i+2)/(i+3));
It is not working because i is integer: when you divide (i)/(i+1) or (i+2)/(i+3), you get a zero in both cases, because when i is positive, denominator is greater than numerator. Zero minus zero is zero, p times zero is zero, so that's what you get.
To fix this problem, declare i as float:
#include <stdio.h>
int main ()
{
float s,p=1.0, i;
int n;
printf("Put a number:");
scanf("%d",&n);
for (i=1;i<=n;++i) {
p*=((i)/(i+1)-(i+2)/(i+3));
}
printf("\n p=%f",p);
return 0;
}
You are using int variables, not float variables, thus i/(i+1) and (i+2)/(i+3) will always evaluate to 0 since it's integer division.
Just use some casts to force the evaluation using floating point arithmetics:
((float)i)/(i+1)-((float)i+2)/(i+3)
Your problem is that integer division truncates rather than returning the floating point results you appear to be looking for:
i/(i+1)
and
(i+2)/(i+3)
are always 0 in C.