简体   繁体   中英

Handling floating-point numbers in Python3

I am an experienced R user and I am trying to learn Python3 on my own since a couple of days. The way Python handles floating-point numbers is really confusing for me at the beginning. For example,

print(1.1+2.2==3.3)

will return False . I know that I can solve this "problem" how Python interprets floating-point numbers by using the decimal module.

import decimal as d
print(d.Decimal("1.1")+d.Decimal("2.2")==d.Decimal("3.3"))

will return True and this is exactly what I wanted.

But how does this work with variables or other functions ? For example, I want to calculate the determinant of the following matrix:

import numpy as np
from numpy import linalg

A = np.array([[1,2],[3,4]])
Det_A = np.linalg.det(A)
print(Det_A)

The result is -2.0000000000000004 but I want the result to be exactly -2. How can I do this ?

Please excuse my imprecise language, I am not a computer scientist. Any advice is welcome.

SciPy seems to be able to calculate the determinant more accurately than NumPy. For example:

import numpy as np
from scipy import linalg

A = np.array([[1,2],[3,4]], dtype=float)

print(np.linalg.det(A))  # => -2.0000000000000004
print(linalg.det(A))     # => -2.0

I'm not sure if this is true in general, but using SciPy versions seems to be preferred and hence it seems reasonable where possible. Eg if you're making a Docker container and the only reason to pull in SciPy was to get a more accurate determinant then I wouldn't do it, but when working locally or if using more functionality then it's probably worth using SciPy.

Also note that R suffers from the same issues when using floating-point maths, for example I get FALSE back when entering 1.1 + 2.2 == 3.3 in R. This can be confirmed by calculating (1.1 + 2.2) - 3.3 , in R this outputs:

4.440892e-16

while Python gives:

4.440892098500626e-16

These are the same values, it's just that Python is more precise at displaying the results.

Would it be ok for your application to cast to integer? print(int(Det_A)) or to just print 2 digits after the decimal point print({:.2f}".format(Det_A))

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM