In this blog post, we will try to figure out how numpy handles seemingly simple math operations. The motivation behind this exploration is to figure out if there are a few foundational operations behind most of the frequently used functions in numpy. For the sake of right level of abstraction, we will not look into addition, subtraction, multiplication, and division.

Pi

Background

pi is an irrational number and computing its value to a certain precision is a challenging task. This video talks in detail how people used to compute pi in the past. At the time of writing this blog post, Google holds the record for computing pi to the highest precision to 100 trilian digits. They used y-cruncher program (it’s free. try it!) with Chudnovsky algorithm to compute pi. Here are the first 100 digits of pi:

Hmm, that looks off. From 16th digit onwards, the values are different. Let’s try to figure out why.

pi =3.141592653589793238462643383279502884pi = np.array(pi, dtype=np.float64)pi =f"{pi:.64f}"np_pi =f"{np.pi:.64f}"assert np_pi == pi

Okay, so it seems like converting 36 digits of pi to 64 bit precision went wrong from 16th digit onwards. What a waste of last 20 digits of pi due to floating point errors! Anyways, let’s move on.

Power

Let’s find out what happens when you execute the following code in numpy.