Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Handling extremly small numbers in C++

Let a and b be two numbers between 0 and 1. How to calculate pow(a,10000)/(pow(a,10000)+pow(b,10000))?

Ex:- This following code gives -nan as output instead of 0.5

double a = 0.5,b = 0.5; 
cout<<pow(a,10000)/(pow(a,10000)+pow(b,10000)); 
like image 665
weedfarmer Avatar asked Jul 08 '15 20:07

weedfarmer


1 Answers

There is no simple generic solution to your problem. Writing computer programs dealing with very small and/or very big numbers is an "art of science" - often called numerical analysis. Typical tricks involves scaling before calculating.

In your case each pow(..) is rounded to zero because that is the closest representable value to the real result. After that you do 0/(0 + 0) which is NaN, i.e. Not a Number.

You could go for long double:

long double a = 0.5;
long double b = 0.5;
long double c =pow(a,10000);
long double d =pow(b,10000);
cout << c << endl;
cout << d << endl;
cout<<c/(c+d);

which result in:

5.01237e-3011
5.01237e-3011
0.5

but that will only help for " a while". Increasing the power a bit (just an extra zero) and the problem is back.

long double a = 0.5;
long double b = 0.5;
long double c =pow(a,100000);
long double d =pow(b,100000);
cout << c << endl;
cout << d << endl;
cout<<c/(c+d);

0
0
nan

So you need to write a very complicated class yourself or study how this is handle in numerical analysis.

Start here: https://en.wikipedia.org/wiki/Numerical_analysis or https://en.wikipedia.org/wiki/Arbitrary-precision_arithmetic

If you know the exp is the same all three place then you can do:

double a = 0.5,b = 0.5; 
int exp = 10000;
//cout<<pow(a,exp)/(pow(a,exp)+pow(b,exp)); is the same as:
cout<<1/(1+pow(b/a,exp)); 

It will work better for most a and b values but don't expect any precision. If a and b just differs a little bit, you'll get 0 (for a less b) or 1 (for b less a). But the NaN part will be solved.

like image 113
Support Ukraine Avatar answered Nov 15 '22 10:11

Support Ukraine