Wartości zmiennoprzecinkowe podwójnej precyzji w Pythonie? [Zamknięte]


84

Czy istnieją typy danych o większej precyzji niż zmiennoprzecinkowe?


3
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.
bsplosion

Odpowiedzi:


53

Typ danych dziesiętnych

  • 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 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.


15
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).


1
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


1

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)

1
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.
Wauzl
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.