W rzeczywistości są to dwa pytania z różnymi odpowiedziami. 1: wartości o podwójnej precyzji w Pythonie to liczby zmiennoprzecinkowe, a 2: typ danych o lepszej dokładności niż liczba zmiennoprzecinkowa byłby dziesiętny. Czy takie pytania można jakoś podzielić? Zaakceptowane adresy odpowiedzi nr 2, ale najczęściej głosowane adresy odpowiedzi nr 1.
W przeciwieństwie do binarnych liczb zmiennoprzecinkowych opartych na sprzęcie, moduł dziesiętny ma precyzję modyfikowalną przez użytkownika (domyślnie 28 miejsc), która może być tak duża, jak potrzeba dla danego problemu.
Jeśli naciskają na Ciebie problemy z wydajnością, spójrz na GMPY
Gdybym zadawał oryginalne pytanie, odpowiedzią byłby @ larsmans (chociaż formalnie nie jest to temat).
Piotr Findeisen
@PiotrFindeisen gdzie jest ta odpowiedź?
Proszę o pomoc,
Nie mam pojęcia, ale teraz odnosiłbym się do @FredFoo. Ogólnie „Wartości zmiennoprzecinkowe podwójnej precyzji w Pythonie?” → „ float-s są podwójnej precyzji”
Piotr Findeisen
120
floatTyp wbudowany w Pythonie ma podwójną precyzję (to C doublew CPythonie, Java doublew Jythonie). Jeśli potrzebujesz większej precyzji, zdobądź NumPy i użyj jego numpy.float128.
Najwyraźniej numpy.float128często ma 64-bitową precyzję w systemie 64-bitowym. numpy.float128(1) + numpy.float128(2**-64) - numpy.float128(1)zwraca 0.0. Zobacz stackoverflow.com/a/29821557/420755
Jeff,
0.1 + 0.2 nie jest dokładną wartością 0.3 w Pythonie, w każdym innym języku jest to problem zmiennoprzecinkowy, ale nigdy podwójny. Dlaczego w Pythonie nie jest to dokładne 0,3?
Oprogramowanie Fusca
@FuscaSoftware To problem także w innych językach. Podwójne IEEE nie mogą dokładnie odpowiadać 0,3. To brzmi jak artefakt formatowania.
Hans Musgrave
17
W przypadku niektórych aplikacji możesz użyć Fractionzamiast liczb zmiennoprzecinkowych.
>>> from fractions import Fraction
>>> Fraction(1, 3**54)
Fraction(1, 58149737003040059690390169)
(W przypadku innych aplikacji jest decimal, jak sugerują inne odpowiedzi).
jak wybrać między dziesiętnym a ułamkowym? Ułamek wydaje się lepszy, ponieważ może reprezentować ciągłe ułamki, których, jak sądzę, Decimal nie może?
Janus Troelsen
1
@Janus: rozważ swoje wymagania i wybierz to, które lepiej do nich pasuje. Użyj, Decimalgdy chcesz pracować z przybliżonymi liczbami, które mają stałą (ale konfigurowalną) precyzję. Używaj, Fractiongdy chcesz pracować z dokładnymi stosunkami i jesteś przygotowany na sprostanie nieograniczonym wymaganiom dotyczącym przechowywania.
Gareth Rees
Czy Fraction obsługuje wszystkie operacje, które można wykonać za pomocą float?
danijar
14
Może potrzebujesz Decimal
>>> from decimal import Decimal
>>> Decimal(2.675)
Decimal('2.67499999999999982236431605997495353221893310546875')
Oto moje rozwiązanie. Najpierw tworzę losowe liczby za pomocą random.uniform, formatuję je do łańcucha z podwójną precyzją, a następnie konwertuję je z powrotem na zmiennoprzecinkowe. Możesz dostosować precyzję, zmieniając „.2f” na „.3f” itp.
Dobrze. Podwójna precyzja oznacza binarną reprezentację zmiennej o podwójnej długości w porównaniu z binarną reprezentacją zmiennej typu float. Nie dwa miejsca po przecinku.
kravemir
Masz rację. Mogłem użyć złych kryteriów wyszukiwania, kiedy sam miałem ten problem i to jest wynik. Inni mogą przeszukać ten sam problem, co ja i skończyć tutaj. Miejmy nadzieję, że znajdą jakąś ulgę. :)
Bittikettu
To najgorszy sposób, jaki przychodzi mi do głowy, aby zaokrąglić liczbę zmiennoprzecinkową do dwóch miejsc po przecinku. Powinieneś użyć przynajmniej numpy.floor(100*a)/100do skrócenia liczby ado dwóch miejsc po przecinku.
Odpowiedzi:
Typ danych dziesiętnych
Jeśli naciskają na Ciebie problemy z wydajnością, spójrz na GMPY
źródło
float
-s są podwójnej precyzji”float
Typ wbudowany w Pythonie ma podwójną precyzję (to Cdouble
w CPythonie, Javadouble
w Jythonie). Jeśli potrzebujesz większej precyzji, zdobądź NumPy i użyj jegonumpy.float128
.źródło
numpy.float128
często ma 64-bitową precyzję w systemie 64-bitowym.numpy.float128(1) + numpy.float128(2**-64) - numpy.float128(1)
zwraca0.0
. Zobacz stackoverflow.com/a/29821557/420755W przypadku niektórych aplikacji możesz użyć
Fraction
zamiast liczb zmiennoprzecinkowych.>>> from fractions import Fraction >>> Fraction(1, 3**54) Fraction(1, 58149737003040059690390169)
(W przypadku innych aplikacji jest
decimal
, jak sugerują inne odpowiedzi).źródło
Decimal
gdy chcesz pracować z przybliżonymi liczbami, które mają stałą (ale konfigurowalną) precyzję. Używaj,Fraction
gdy chcesz pracować z dokładnymi stosunkami i jesteś przygotowany na sprostanie nieograniczonym wymaganiom dotyczącym przechowywania.Może potrzebujesz Decimal
>>> from decimal import Decimal >>> Decimal(2.675) Decimal('2.67499999999999982236431605997495353221893310546875')
Arytmetyka zmiennoprzecinkowa
źródło
Oto moje rozwiązanie. Najpierw tworzę losowe liczby za pomocą random.uniform, formatuję je do łańcucha z podwójną precyzją, a następnie konwertuję je z powrotem na zmiennoprzecinkowe. Możesz dostosować precyzję, zmieniając „.2f” na „.3f” itp.
import random from decimal import Decimal GndSpeedHigh = float(format(Decimal(random.uniform(5, 25)), '.2f')) GndSpeedLow = float(format(Decimal(random.uniform(2, GndSpeedHigh)), '.2f')) GndSpeedMean = float(Decimal(format(GndSpeedHigh + GndSpeedLow) / 2, '.2f'))) print(GndSpeedMean)
źródło
numpy.floor(100*a)/100
do skrócenia liczbya
do dwóch miejsc po przecinku.