Changing the limitation of calculation in Python [duplicate] - python

This question already has answers here:
Is floating point math broken?
(31 answers)
Closed 3 years ago.
I have a question but I do not know what is the relevant part to search or read about.
I would like to calculate some values but Python gives me a rounded value. For example np.exp(3.832781064493026e-31) = 1 but it should not be 1. What is the way of avoiding these approximations? It should be like 1.00000000000000000000000000000384922.

There is mpmath, numpy's multiprecission cousin:
from mpmath import mp
mp.dps = 100
print(mp.exp(3.832781064493026e-31))
# 1.000000000000000000000000000000383278106449302614152558221812007328689735262269801950763925404522797
print(np.expm1(3.832781064493026e-31))
# 3.832781064493026e-31
print(1+np.expm1(3.832781064493026e-31))
# 1.0
# the second term is eaten away by the 64 bit precission (about 16 decimal digits)
Note that mpmath is quite slower than numpy, doesn't work with numpy's arrays and doesn't mix well with other libraries.
Alternatively, especially if you want to calculate exp(x)-1, there is numpy's expm1. This function is introduced because of the precission problems you run into when first calculating exp(x) and then subtracting 1 for small values of x. A better explanation can be found in this post and more thoroughly here.

Related

math.pi doesn't give me the good value [duplicate]

This question already has answers here:
Is floating point math broken?
(31 answers)
Closed 1 year ago.
I use math.pi with python:
import Decimal as dc
dc.getcontext().prec=100
pi = dc.Decimal(math.pi)
and I get:
3.141592653589793115997963468544185161590576171875
and on Internet, I get:
3,141592653589793238462643383279502884197169399375
Why doesn't python give a good value? How to improve the situation?
I tried with and without Decimal.
As indicated in the comments and in the documentation of Python math module, math.pi holds a floating-point value. Floating-point is inaccurate by design, because there is a finite number of bits dedicated to keeping the precision. You can read https://docs.python.org/3/tutorial/floatingpoint.html to understand how float is represented, and how this will impact you during programming (in all languages, not only Python).
How to get your accurate value of pi? As mentioned by Tom Karzes, you can use Decimal module and feed it with as many digits as you want. Let's take the first 30 digits of pi from https://www.angio.net/pi/digits/pi1000000.txt, and your code would look like this:
pi_30_decimal_places = Decimal("3.141592653589793238462643383279")

Why does `1e500 - 1e500` result in `nan` [duplicate]

This question already has an answer here:
What are some possible calculations with numpy or scipy that can return a NaN? [closed]
(1 answer)
Closed 1 year ago.
Not a very important question but I was just curious about the following behavior in Python:
1e500 - 1e500
>>> nan
What is the reasoning for this behavior and why does it not return 0?
I suppose most calculations using 1e500 are pretty weird too but to me at least this 1e500 - 10000 = inf makes sense since the difference would be negligible.
Edit
This question was suggested as holding the answer to my question but in my opinion the answer doesn't explain why this wouldn't be 0, just that it would be NaN.
1e500 is too big to represent in a double precision floating point number, so it turns into inf.
inf-inf gives NaN.
I was thinking of 1e500 as a number, but the real issue is that in Python 1e500 is considered infinity, as it uses whatever floating-point types the underlying platform makes available, which is standard IEEE 754 behavior (Thank you #chpner for that explanation in the comments).
Therefore, the calculation is impossible since infinity - infinity is itself impossible (explained here), which I did not know before.

Getting inaccurate answers when doing math with large numbers in python [duplicate]

This question already has answers here:
Is floating point math broken?
(31 answers)
Closed 1 year ago.
I am writing python code that involves a series of math calculations. One such is the following operation:
result1 = float1 % float2 //modulo operation to find the remainder
where float1 = 6816605016955680000000 and float2 = 1577917828000
The result I get is 1573597498272 (reverse math shows that this is not accurate). I get the same result on Excel or Numbers as well.
However, when I try this on a quad-core system, Excel and Numbers give a very different result which is 1573597828000 (reverse math shows this is accurate). The python program continues to give the same old result even on the quad-core system.
(Python version is 3.7.2 on my system and 3.9 on quad-core system).
What can I do to ensure python gives me the accurate result? Any guidance would be super valuable. Thanks in advance.
Python numbers are not accurate for large numbers, if you want more accurate precision, use the Decimal class:
from decimal import Decimal
Decimal(6816605016955680000000) % Decimal(1577917828000)
Output:
Decimal('1573597828000')
This should give you consistent results across different systems.

Python logarithm math strange result [duplicate]

This question already has answers here:
Is floating point math broken?
(31 answers)
Closed 4 years ago.
What is the explanation for this unexpected results in Python??!;
from math import *
>>>log(1000,10) ## expecting 3.0
2.9999999999999996
>>>1000**(1/3) ## expecting 10.0
9.999999999999998
Basically value of these functions are calculated using some series. As python by default uses floating values, so it calculates values very precisely.
You can see this...
Efficient implementation of natural logarithm (ln) and exponentiation
That`s why it gives these types of result.
You can use Fraction class from fractions to convert these values to integer.
https://docs.python.org/3.1/library/fractions.html

Mathematics and behavior with floats vs ints [duplicate]

This question already has answers here:
Is floating point math broken?
(31 answers)
Why does Python return 0 for simple division calculation?
(6 answers)
Closed 5 years ago.
This is driving me mad... Of all the years I've been using python, this is just now starting to present itself. How I managed to dodge it up until now is beyond me.
If you open a python idle and try this equation...
4/32*100
You'll get '0' as an answer. Now try the same equation using floats....
4.0/32.0*100.0 (or just the first number 4.0/32*100)
You now get an actual percentage.
WTF!?
Is this some kind of python error!? Even a calculation can do the equation and spit out a percentage.
So why can't python see a 4 as 4.0. Better question... What is the interpreter actually seeing if it's not seeing a 4(4.0)?
Someone please clear this up so I can feel professional with python again (lol).
In Python 2, int type division ignores the decimal values of the division.
For example, 1/2 = 0.5, but in int type division, 1/2 will evaluate to 0 because it ignores the decimal values.
Thus, in your case with 4/32*100, 4/32will first evaluate to 0 and then 0*100 will finally equal 0.
On the other hand, in float type division, it will evaluate answers as we would expect (not in a strictly precise definition though, look here for further information).
For Python 2.x, dividing two integers or longs uses integer division, also known as "floor division"(applying the floor function after division)
For Python 3.x, "/" does "true division" for all types.
To make python perform true division, cast any of the denominator for numerator to become float.
float(4)/32*100
or
4/float(32)*100
or doing below to make python 2 division behave like python 3 division
from __future__ import division
4/32*100

Categories

Resources