It's different due to differences in the implementation of the functions. Neither one is perfect due to the nature of floating point.
The ** operator is implemented in floatobject.c and contains a lot of special cases, but none of them are invoked here, so it ultimately reaches the standard C pow function. The math.pow function ultimately does the same thing.
The exp function is a straightforward wrapper around the C function of the same name, defined with a macro in mathmodule.c.
As it happens, exp is more precise (both of the results match, to within the precision allowed by floating point, high-precision answers I calculated in bc). Most likely it is because internally to pow, it is calculating the extended-precision logarithm of the double-precision e value you pass as the first argument, which is slightly smaller than 1.
The fundamental issue is that math.e, which is the number you're calculating the power of, is:
2.718281828459045 09079559829...
Whereas the real value of e is
2.718281828459045 23536028747...
And this error is compounded when you use pow or **, whereas it may not be (or may be using a higher precision value internally) if you're using exp due to the details of the algorithms it uses.
It's different due to differences in the implementation of the functions. Neither one is perfect due to the nature of floating point.
The ** operator is implemented in floatobject.c and contains a lot of special cases, but none of them are invoked here, so it ultimately reaches the standard C pow function. The math.pow function ultimately does the same thing.
The exp function is a straightforward wrapper around the C function of the same name, defined with a macro in mathmodule.c.
As it happens, exp is more precise (both of the results match, to within the precision allowed by floating point, high-precision answers I calculated in bc). Most likely it is because internally to pow, it is calculating the extended-precision logarithm of the double-precision e value you pass as the first argument, which is slightly smaller than 1.
The fundamental issue is that math.e, which is the number you're calculating the power of, is:
2.718281828459045 09079559829...
Whereas the real value of e is
2.718281828459045 23536028747...
And this error is compounded when you use pow or **, whereas it may not be (or may be using a higher precision value internally) if you're using exp due to the details of the algorithms it uses.
exp(x) is implemented at a much lower level than e**x. It is essentially a wrapper for a function in libc. Said function is probably (at some level) using the Taylor series expansion to calculate the value directly (or possibly some other mathematical method, I'm not sure).
On the other hand, e**x is taking a number and raising it to a power. This is an entirely different strategy, and probably less precise in most circumstances. Raising numbers to powers is difficult to do precisely.
You can use exp(x) function of math library, which is same as e^x. Hence you may write your code as:
import math
x.append(1 - math.exp( -0.5 * (value1*value2)**2))
I have modified the equation by replacing 1/2 as 0.5. Else for Python <2.7, we'll have to explicitly type cast the division value to float because Python round of the result of division of two int as integer. For example: 1/2 gives 0 in python 2.7 and below.
Just saying: numpy has this too. So no need to import math if you already did import numpy as np:
>>> np.exp(1)
2.718281828459045
It is E notation for decimal numbers, a compact variant of scientific notation. E notation is used in computer software applications and programming languages, while full scientific notation is used in traditional math notation/typesetting.
The “e” or “E” stands for “× 10^”. Examples:
- 1e-5 = 1 × 10−5 = 0.00001 (the number you gave)
- 0.369E+2 = 0.369 × 102 = 36.9 (another example)
In programming languages, E notation only applies to literals and string conversions. The E is not an operator and cannot be applied to arbitrary expressions. Good examples:
x = 2e4
x == 20000.0 # True
f"{x:e}" # '2.000000e+04'
float("-8e-7") == -0.0000008 # True
Bad examples:
y = 1
z = 2
yEz # NameError: name 'yEz' is not defined
y E z # SyntaxError: invalid syntax
3Ez # SyntaxError: invalid decimal literal
The official Python reference for E notation in numeric literals: https://docs.python.org/3/reference/lexical_analysis.html#floating-point-literals
E notation behaves very differently from the power operator (**) and the pow() function.
10 ** -5, i.e. 10 to the power of negative 5, 1 divided by 10 to the power of 5, or 0.00001.