Questions of Class Homework C++ Intro

Hi, I'm new here just want to ask a question how to calculate and print number 1/1 + 1/2 + 1/4... + 1/100000000 using float and double variables while using a loop?

1
2
3
4
5
6
  cout << " the answer is " << endl;
	for (float i = 1/1; i <= 1/100000000; ++i)
	{
		VarF1 += i;
	}
		cout << " Var1 now contains " << VarF1 << endl;

Thank you.
I can get to around 3 * 10^7 before my laptop gives up:
1
2
3
4
5
6
7
8
9
10
11
#include <iostream>

int main()
{
    float VarF1 = 1;
    for (float i = 2; i <= 30000000; i += 2)
    {
        VarF1 += (1.0/i);
    }
    std::cout << VarF1 << '\n';
}
Looking at just the denominators, we get the following:
1, 2, 4, 8, 16, ...
Notice how these are all powers of 2.
1
2
3
4
5
6
20 = 1
21 = 2
22 = 4
23 = 8
24 = 16
...

Do you see the pattern?

We are incrementing the exponent, which gives our denominator, then we take the reciprocal of it. We add this to the sum. As our base is 2 but the maximum denominator(100000000) is in base 10(decimal), we'll need to convert that such that
 
2exp >= 100000000
. This is just some basic maths, so we end up with
 
226.5754247591 ≈ 100000000
. We'll round that up to 27.
Here's some boilerplate code that starts off what I explained above.
1
2
3
4
double sum = 0;
for( int i = 0; i <= 27; i++ ) {
    
}
Last edited on
jaitoine,

Could you clarify your series please. As it stands it does not form a pattern.

1/1 + 1/2 + 1/4 + .... what goes in here? + ... + 1/100000000



100000000 is not a power of 2, so I'm not sure that @integralfx's proposal is correct. If it was 1/1 + 1/2 + 1/4 + 1/8 + 1/16 + ... then that's just a geometric series (first term 1, common ratio 1/2) and such a series can be summed by formula: there would be no point in doing a sum.

If the denominators are 1 2 4 ... then this is not consistent with i incrementing by 2 every time.

Did you mean 1/1 + 1/2 + 1/3 + 1/4 + ... + 1/100000000? This would be part of the harmonic series, which diverges to infinite terms, so it seems odd to be asking for its partial sums. Exactly the same would be true of 1/2 + 1/4 + 1/6 + 1/8 + ...


So, please confirm what your series actually is.
lastchance: I took the first 1 separately and then "formed a pattern" with the remaining terms but, admittedly, it's still second-guessing the OP
Last edited on
for (float i = 1/1; i <= 1/100000000; ++i)
This won't work for 3 reasons.

1. Your test condition uses integer math (1/100000000). Integer division rounds down, so this is the same as 0. To get the fraction, you'd need to express one or both numbers in floating point (1.0/100000000)
2. The initial value of i (1) is not than 1.0/100000000. So the loop won't execute even once.
3. The increment value of 1 is wrong.

Looking at that series again, the easy thing to increment is the denominator itself. It multiplies by 2 on each iteration: Remember that for loops don't have to increment by 1 each time. They can just as easily multiply by 2:
for (float denom = 1; denom <= 100000000; denom *= 2)
Then inside the for loop you can add to the sum.
VarF1 += 1/denom;

Before outputting the numbers, set the precision to something very high, like:
std::cout.precision(20);
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#include<iostream>
using namespace std;

int main()
{
    double num=0,div=2.0,divStore=0.0,store=0.0;
    cout<<"\nEnter The Number : ";
    cin>>num;
    num--;
    while(num!=0)
    {
        divStore=1/div;
        store+=divStore;
        div*=2;
        num--;
    }
        store+=1;
        cout<<"\n The Sum is : "<<store<<endl;
        return 0;
}
Sorry, I meant the sum of 1/1 + 1/2 + 1/3 + ..... 1/100000000
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#include<iostream>

int main()
{
    int n{};
    double answer{};
    std::cout << "Enter 'n' \n";
    std::cin >> n;
    if(n!= 0)
    {
         for(int i = 1; i <= n; ++i)
         {
            answer += 1.0/i;
         }
         std::cout << "Answer is " << answer << "\n";
    }
    else
    {
         std::cout << "Answer not defined! \n";
    }
}
Make sure that you try it with both float and double answers, @jaitoine: I think you might see some important effects of precision/rounding.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#include <iostream>
using namespace std;

int main()
{
   float  sumFloat  = 0.0;
   double sumDouble = 0.0;
   for ( int i = 1; i <= 100000000; i++ )
   {
      sumFloat  += 1.0 / i;
      sumDouble += 1.0 / i;
   }
   cout << "Sum with float  precision: " << sumFloat  << endl;
   cout << "Sum with double precision: " << sumDouble << endl;
}
Last edited on
Be sure to set the precision very high:
std::cout.precision(40);
After you try it with both float and double, also try computing it with the denominators going forwards and backwards. In other words, also try computing it as:
1/100000000 + 1/99999999 + 1/99999998 + ... + 1/3 + 1/2 +1/1

You will find that the answers differ significantly with float. Going backwards is much more accurate. Can you figure out why?
Can't resist!

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
#include <iostream>
#include <iomanip>
using namespace std;

int main()
{
   float  sumFloat  = 0.0;
   double sumDouble = 0.0;
   for ( int i = 1; i <= 100000000; i++ )
   {
      sumFloat  += 1.0 / i;
      sumDouble += 1.0 / i;
   }
   cout << "Sum with float  precision: " << sumFloat  << endl;
   cout << "Sum with double precision: " << sumDouble << endl;


   cout << "\n Now let's go backwards ... " << endl;
   sumFloat  = 0.0;
   sumDouble = 0.0;
   for ( int i = 100000000; i > 0; i-- )
   {
      sumFloat  += 1.0 / i;
      sumDouble += 1.0 / i;
   }
   cout << "Sum with float  precision: " << sumFloat  << endl;
   cout << "Sum with double precision: " << sumDouble << endl;
}


Sum with float  precision: 15.4037
Sum with double precision: 18.9979

 Now let's go backwards ... 
Sum with float  precision: 18.8079
Sum with double precision: 18.9979


You're right: that's pretty cool!
Last edited on
Thanks @lastchance
Last edited on
dhayden wrote:
Can you figure out why?


Why?
Why?

It's because of the way computers represent floating point numbers. Remember scientific notation? That's where you write a number as something like 1234x1012. Here 1234 is called the mantissa and 12 is the exponent. Computers represent floating pointer numbers in the same way, although all numbers are binary. C++ float is usually represented in 4 bytes with 24 bits of mantissa and 8 bits of exponent.

Those 24 bits of mantissa are equivalent to about 7 decimal digits.

Now consider what happens when you add 18.12345 to 1/100000000 = 0.00000001. There aren't enough bits in the floating point format to handle the wide difference between these values. So you lose precision.

On the other handle if you add 1/100000000 to 1/9999999, the numbers have about the same magnitude so you can get a pretty accurate result. Adding 1/9999998 gives another result that is pretty accurate. As you keep adding values, the sum increases, but so do the terms being added.
Thank you for the brief explanation.
Topic archived. No new replies allowed.