Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Math.Exp of large negative number

Tags:

c#

On my machine, and current .net version Math.exp(-1000) returns 0.0, as is reasonable because it is a number that is too small to represent as a double.

Can I rely on this to remain so on other machines, and in future .net builts? Msdn tells me Math.exp(Double.NegativeInfinity) return 0.0 (which I therefore expect to remain so in future), but what about -1000?

like image 381
willem Avatar asked Sep 08 '10 12:09

willem


2 Answers

The Math.Exp() function is defined as operating on double-precision types. Note that exp(-1000) == 5.08e-435, far below the smallest absolute value that can be expressed in a double.

I think it's safe to say that any environment where IEEE floating point numbers are used, exp(-1000) will be 0.0. It's very unlikely that .Net will ever leave IEEE floating point. In more general terms I'm guessing you're interested in whether small quantities reliably round to zero. In short, yes, in IEEE.

However, it is probably best to not design this behaviour into your code. As Darin suggests, compare floating point values within a tolerance. If you have a reason for working with very small or large numbers, consider tracking the quantity as a logarithm and performing operations in the logarithmic domain (if you need to multiply, add the logarithms, etc.). You could use a high precision math library, but even with those as numbers become very small the calculation can be subject to large roundoff errors and poor numerical stability.

Finally if your intent is to compute 1.0 - Math.Exp(-num) or Math.Exp(-num) - 1, look for a library function that directly computes these to get the best precision.

like image 116
jbarlow Avatar answered Nov 06 '22 19:11

jbarlow


No, you can never rely that a variable of type double is exactly equal to something. Never write something like this. Never use the == operator to compare two double operands:

double d = ...
if (d == 0.0) {

}

Instead you should define a desired precision and always work with this precision:

double epsilon = 1e-5;
double d = ...
if (Math.Abs(d - 0.0) < epsilon) {

}
like image 29
Darin Dimitrov Avatar answered Nov 06 '22 19:11

Darin Dimitrov