How to multiply a very small number with itself more than 100 times in c++?

3.1k views Asked by At

I am trying to develop a c++ program to multiply a number (say,2.45784e-05) with itself 28224 times. After multiplication, I have to do another task on the output. To multiply the number with itself, I write a C++ program as follows:

 #include<iostream>
    using namespace std;
    int main() {
        long double x = 2.45784e-05, y = 1;
        cout << "Before multiplication, x= " << x << endl;
        for (int i = 0; i < 28224; i++) {
            y = y * x;
            cout <<i+1<<". "<< "y=" << y << endl;
        }

        return 0;
    }

But, the program gives accurate output up to 1075 times. After that, it gives 0 as output. The results are:

Before multiplication, x= 2.45784e-05
1. y=2.45784e-05
2. y=6.04098e-10
3. y=1.48478e-14
4. y=3.64934e-19
.
.
.
1073. y=1.15885e-4946
1074. y=3.6452e-4951
1075. y=0
1076. y=0
.
.
.
28223. y=0

My friends advised me to multiply a constant with x every time after multiplying with itself. But I don't get the point how to multiply a constant with it. Please give me a solution to get the output.

3

There are 3 answers

1
Leontyev Georgiy On BEST ANSWER

Every time you multiply your number with itself, it increases the amount of required digits to keep. Well, to be honest, even from these 1075, I think mostly half are correct enough, or even less, others will be converged to nearby numbers that can be represented as long double. To do the trick you want you need to use some 3rdparty libraries with arbitrary-presicion maths. Look at the list here:

https://en.wikipedia.org/wiki/List_of_arbitrary-precision_arithmetic_software

What your friends want you to do won't help much: constant multiplication will move the decimal point, but won't decrease the amount of digits needed to evaluate.

EDIT: @Borgleader's solution looks pretty good (boost:multiprecision).

0
brian beuning On

Given x = 2.45784e-05 and y = 28224 and you want x^y (power). Find s (scale) such that z = x * s, 0 < z < 1 (s = 10^6) then your answer is (z/s) ^ y = z^y / s^y. If s is 10^6, then you can compute s^y as 10^(6*y).

I expect z^y to still overflow, but it will happen for a higher exponent and then you can refine the idea. Hint: try using s as a power of 2.

0
EmDroid On

The problem here actually isn't the precision (or by itself, it is only a part of the problem, but not the essential one).

The main problem here is the range, that the resulting number is too small to be represented in double (the result exponent is going out of range of the minimum exponent of the double representation). So for the computer, it effectively is 0.

The idea to multiply the value by some number to make it bigger (i.e. "scale") can thus work, and you'll then need to compensate the result exponent.

Also note, that if you want to multiply the same number multiple/a lot of times, you can use pow(num, N) instead, which will be much faster if the N is big.