I am writing a simple C program that prints the sum of the harmonic series like:
1 + 1/2 + 1/3 + ...... + 1/n
My program is:
#include<stdio.h>
void main(){
int n,i;
float num=0, tmp=0;
scanf("%d", &n);
for(i=1;i<=n;i++){
tmp = 1/i;
num = num + tmp;
}
printf("%f", num);
}
As per my understanding, if n=4, the output must be: 2.03333
But the output comes as 1.00000
1/i is not a float value, it is an int of value 0 or 1, because of integer division rules.
The value is 1 for 1/1 otherwise 0. Adding all of them up results in 1.
This is a floating point value:
1.0/i
Adding them up should give the desired result.
To be precise, I should say that 1.0 is a double.
In order to work with actually a float value to match the float variable, use 1.0f. Both are floating point values in contrast to integer values.
As 1 and i are integers, dividing these two will be integer and you will get 0 for i > 1 in this case. You can cast i using (float)i and you will have 1/(float)i.
Related
Given a harmonic series 1 - 1/2 + 1/3 - 1/4... = ln(2), is it possible to get a value of 0.69314718056 using only float values and using only basic operations (+,-,*,/). Are there any algorithms which can increase the precision of this calculation without going to unreasonably high values of n (current reasonable limit is 1e^10)
What I currently have: this nets me 8 correct digits -> 0.6931471825
EDIT
The goal is to compute the most precise summation value using only float datatypes
int main()
{
float sum = 0;
int n = 1e9;
double ans = log(2);
int i;
float r = 0;
for (i = n; i > 0; i--) {
r = i - (2*(i/2));
if(r == 0){
sum -= 1.0000000 / i;
}else{
sum += 1.0000000 / i;
}
}
printf("\n%.10f", sum);
printf("\n%.10f", ans);
return 0;
}
On systems where a float is a single-precision IEEE floating point number, it has 24 bits of precision, which is roughly 7 or (log10(224)) digits of decimal precision.
If you change
double ans = log(2);
to
float ans = log(2);
You'll see you already get the best answer possible.
0.6931471 82464599609375 From log(2), casted to float
0.6931471 82464599609375 From your algorithm
0.6931471 8055994530941723... Actual value
\_____/
7 digits
In fact, if you use %A instead of %f, you'll see you get the same answer to the bit.
0X1.62E43P-1 // From log(2), casted to float
0X1.62E43P-1 // From your algorithm
#ikegami already showed this answer in decimal and hex, but to make it even more clear, here are the numbers in binary.
ln(2) is actually:
0.1011000101110010000101111111011111010001110011111…
Rounded to 24 bits, that is:
0.101100010111001000011000
Converted back to decimal, that is:
0.693147182464599609375
...which is the number you got. You simply can't do any better than that, in the 24 bits of precision you've got available in a single-precision float.
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);
I have a program here that is supposed to sum up the series
1+1/2+1/3+1/4... etc
The only user entry is to enter how many times you want this sum to run for.
However, I keep getting the sum one.
#include <stdio.h>
int main(void)
{
int b,x; /* b is number of times program runs and x is the count*/
float sum;
printf("Enter the number of times you want series to run.\n");
scanf("%d", &b);
printf("x sum\n");
for(x=1,sum=0;x<b+1;x++)
{
printf("%d %9.3f\n",x, (sum +=(float)(1/x)));
}
return 0;
}
I don't quite get why it isn't working. As you can see, I did tell it to print x and when it did, x was incrementing correctly.The sum just kept adding up to one.
You have misplaced parentheses so you're doing integer division for 1/x and getting 0 for any value of x > 1.
I suggest you change:
printf("%d %9.3f\n",x, (sum +=(float)(1/x)));
to:
printf("%d %9.3f\n",x, (sum += 1.0f/x));
Two problems: one dull, one interesting.
1) 1 / x will be imprecise since 1 and x are both integral types and so the computation will be done in integer arithmetic. All the cast does is convert the resultant integral type to floating point. To resolve this, write 1.0 / x. Then 'x' is promoted to floating point prior to the division.
2) You should reverse the order of the for loop:
sum = 0.0;
for(x = b; x >= 1; --x)
(I've also moved the initialisation or sum from the for loop as sum = 0 is an expression of type float but x = b is an expression of type int so you ought not use the comma operator as they have different data types.)
The reason is subtle: you should only add floating points of similar magnitude. Doing the loop my way means the smaller values are added first.
The effect will be noticeable for high values of b; try it. Your original way will always understate the sum.
The problem is integer division when you do 1/x, which always result in 0 as long as x is greater than 1. Even it you later convert this to a float, the "damage" is already done. An easy fix would be to change the division to 1.0f/x.
Since you have declared x as an int, (1/x) returns 1 when x is 1 and 0 for x>1. So, sum remains 1. So you get the same result.
So, change (1/x) to 1.0f/x, so that the result is returned as a float
Here you are computing 1/x in which the fractional value is truncated. Converting it into float after the original value has been truncated doesn't make sense.
So change this to:-
printf("%d %9.3f\n",x, (sum +=(float)(1/x)));
to
printf("%d %9.3f\n",x, (sum += 1.0f/x));
The expression (1/x) will always be integer division. For the first run this will be 1/1 giving you 1. However, next time round it will be 1/2 which is 0. Basically for 1/x where x>1 the answer will be zero.
To get around this write the expression as 1.0/x which will cause x to be promoted to a double, giving you double division.
Could someone tell me why the following code is outputting 0 at the marked line?
It seems as if everything is correct but then when I try to get the result near the end it's giving me 0 each time.
#include <stdio.h>
int main() {
// Gather time-lapse variables
int frameRate, totalLengthSecs;
printf("How many frames per second: ");
scanf("%i", &frameRate);
printf("--> %i frames confirmed.", frameRate);
printf("\nDesired length of time-lapse [secs]: ");
scanf("%i", &totalLengthSecs);
printf("--> %i seconds confirmed.", totalLengthSecs);
int totalFrames = frameRate * totalLengthSecs;
printf("\nYou need %i frames.", totalFrames);
// Time-lapse interval calculation
int timeLapseInterval = totalLengthSecs / totalFrames;
printf("\n\n%i", timeLapseInterval); // <-- this prints 0
return 0;
}
In short: Integer division truncates
You need the following:
double timeLapseInterval = (double) totalLengthSecs / (double)totalFrames;
printf("\ntimeLapseInterval : %f \n", timeLapseInterval);
You are performing integer math.
Math between two integers will produce an integer. And the result will be rounded towards zero.
This line:
totalLengthSecs / totalFrames;
Is likely producing a result that's between 0 and 1. And getting rounded to 0
You are printing integers and therefore it will round down the value.
timeLapseInterval / totalFrames will be (1 / frameRate) which will be < 1 unless frameRate is 1 (or 0 in which case you have an error dividing by 0)
When you divide 2 numbers in C and the denominator is integer, the compiler intends it as an integer division. Therefore, if you divide 1 divided 2, it returns zero and not 0.5
Moreover, your output variable is an integer too, hence, if you expect decimal outputs, you won't get it.
You can fix it by doing:
float timeLapseInterval = totalLengthSecs / (float)totalFrames;
printf("\n\n%f", timeLapseInterval);
I hope this helps
I was writing this code in C when I encountered the following problem.
#include <stdio.h>
int main()
{
int i=2;
int j=3;
int k,l;
float a,b;
k=i/j*j;
l=j/i*i;
a=i/j*j;
b=j/i*i;
printf("%d %d %f %f\n",k,l,a,b);
return 0;
}
Can anyone tell me why the code is returning zero for the first and third variables (k and a)?
Are you asking why k and a show up as zero? This is because in integer division 2/3 = 0 (the fractional part is truncated).
What I think you are experiencing is integer arithmetic. You correctly suppose l and b to be 2, but incorrectly assume that k and a will be 3 because it's the same operation. But it's not, it's integer arithmetic (rather than floating-point arithmetic). So when you do i / j (please consider using some whitespace), 2 / 3 = 0.33333... which is cast to an int and thus becomes 0. Then we multiply by 3 again, and 0 * 3 = 0.
If you change i and j to be floats (or pepper your math with (float) casts), this will do what you expect.
You haven't said what you're getting or what you expect, but in this case it's probably easy to guess. When you do 'a=i/j*j', you're expecting the result to be roughly .2222 (i.e. 2/9), but instead you're getting 0.0. This is because i and j are both int's, so the multiplication and (crucially) division are done in integer math, yielding 0. You assign the result to a float, so that 0 is then converted to 0.0f.
To fix it, convert at least one operand to floating point BEFORE the division: a = (float)i/j*j);
this is due to how the c compiler treats int in divisions:
#include <stdio.h>
int main()
{
int i=2;
int j=3;
int k,l;
float a,b;
k=i/j*j; // k = (2/3)*3=0*3=0
l=j/i*i; // l = (3/2)*2=1*2=2
a=i/j*j; // same as k
b=j/i*i; // same as b
printf("%d %d %f %f/n",k,l,a,b);
return 0;
}
If you're asking why k and a are 0: i/j*j is the same as (i/j)*j. Since j is larger than i, i/j is 0 (integer division). 0*j is still 0, so the result (k) is 0. The same applies to the value of a.
it doesn’t matter if you’re variable is float or not, as long you’re using
integer / integer , you’ll get 0,
but because you’re using a float output, you get 0.0