Python: Decimals with trigonometric functions

I have a little problem, look:

>>> import math >>> math.sin(math.pi) 1.2246467991473532e-16 

This is not what I learned in my calculus class (actually it was 0)

So now my question is:

I need to do heavy trigonometric calculus with Python. Which library can I use to get the correct values?

Can I use Decimal?

EDIT:

Sorry, I mean another thing.

What I want is to do this:

 >>> awesome_lib.sin(180) 0 

or that:

 >>> awesome_lib.sin(Decimal("180")) 0 

I need a librarian who does good trigonometric calculus. Everyone knows that the 180 ° sin is 0, I need a library that can do this too.

+4
source share
5 answers

1.2246467991473532e-16 is close to 0 - there are 16 zeros between the decimal point and the first significant digit - much more than 3.1415926535897931 ( math.pi value) is close to pi. The correct answer is sixteen decimal places!

So, if you want sin(pi) to be 0, just round it to a reasonable number of decimal places. 15 looks good to me and should be a lot for any application:

 print round(math.sin(math.pi), 15) 
+14
source

Pi is an irrational number , so it cannot be accurately represented using a finite number of bits. However, you can use some library for symbolic calculations, such as sympy .

 >>> sympy.sin(sympy.pi) 0 

Regarding the second part of your question, if you want to use degrees instead of radians, you can define a simple conversion function

 def radians(x): return x * sympy.pi / 180 

and use it as follows:

 >>> sympy.sin(radians(180)) 0 
+10
source

If you find that the result is unexpected, I dare to suggest that you look at this text: What every computer scientist needs to know about floating point arithmetic

It is really worth it.

+5
source

you can also try gmpy or real

in gmpy you can explicitly specify the precision:

  gmpy.pi(256) 

in real.py you can use the pa () function:

  from real import pa,pi pa(pi) 
0
source

The short answer is Decimal.cos () and Decimal.sin () can be implemented from the implementation of Decimal.exp (), breaking all even members into cos () and all odd members into sin () and alternating each sign between positive and negative in both series. The loop does not require any changes that calculate only N terms based on the configured precision (Decimal.getcontext (). Prec).

Long answer - Python decimal.Decimal supports the exp () function, which takes only a real number argument (unlike exp () in the R language) and calculates an infinite series only up to the number of terms based on the configured precision (decimal.Decimal.getcontext () . Prec).

Currently, even expressions calculate cosh (), and odd terms calculate sinh (). Their sum is returned as the result of exp (). If the sign of each member has been changed to alternate between positive and negative in each row, a series of even members will calculate cos (), and a series of odd members will calculate sin ().

Also, like R, this change may allow Decimal.exp () to support complex arguments, so exp (1j * x) can return Decimal.cos (x) + 1j * Decimal.sin (x).

0
source

Source: https://habr.com/ru/post/1415626/


All Articles