2012-01-30 8 views
19

Jaką dokładność odwzorowuje numpy.float128 wewnętrznie? Czy to __float128 czy długie podwójne? (lub coś zupełnie innego !?)Jaka jest wewnętrzna precyzja pliku numpy.float128?

Potencjalne pytanie na następcę, jeśli ktokolwiek wie: czy w C można bezpiecznie rzucić __float128 na podwójne (16-bajtowe) podwójne, z samą stratą precyzji? (chodzi o połączenie z biblioteką C, która działa na długich debelach).

Edytuj: W odpowiedzi na komentarz platforma nosi nazwę "Linux-3.0.0-14-generic-x86_64-with-Ubuntu-11.10-oneiric". Teraz, jeśli numpy.float128 ma różną precyzję w zależności od platformy, to jest to dla mnie przydatna wiedza!

Dla jasności, jest to precyzja Jestem zainteresowany, a nie wielkością elementu.

+0

"Wersje z następującą liczbą odpowiadają słowom, które są dostępne na konkretnej platformie, z której korzystasz, mają co najmniej tyle bitów" wydaje się jasne. 128 bitów. Co było w tym mylące? Jest to platforma specyficzna i nie wymieniono platformy, co uniemożliwiłoby udzielenie odpowiedzi na zadane pytanie. Proszę ** zaktualizować ** pytanie z dokładnymi informacjami o platformie Python. Podpowiedź: jest pakiet 'platformowy'. –

+1

"wydaje się jasne" - zakładając, że mówi także, co się dzieje, gdy tego rodzaju typ nie jest dostępny na konkretnej platformie. –

+3

Założę się, że odległa precyzja jest niezależna od platformy, więc informacje z pewnością są przydatne. Mogę * założyć *, że float128 mapuje wewnętrznie na coś podobnego do __float128, ale długie podwójne to także 128 bitów w moim systemie, więc może to być racjonalnie. –

Odpowiedz

7

Zalecane jest użycie longdouble instead of float128, ponieważ jest to całkiem niezła a mess, ATM. Python przesyła go do float64 podczas inicjalizacji.

Wewnątrz numpy może to być podwójne lub podwójne długie. Jest on zdefiniowany w npy_common.h i zależy od twojej platformy. Nie wiem, czy możesz umieścić go od razu w swoim kodzie źródłowym.

Jeśli nie potrzebujesz wydajności w tej części swojego algorytmu, bezpieczniejszym sposobem może być wyeksportowanie jej do ciągu znaków i później użycie strold.

+1

Czy w pamięci znajduje się poprawnie rzut wskaźnika na tablicę float128 na długi podwójny? To * jest * krytyczne pod względem wydajności;) –

+1

Co więcej, czytanie npy_common.h, wydaje się sugerować, że jest wrażliwe na zależną od platformy długość długiego podwójnego (tj. Używa długiego podwójnego, jeśli długie podwójne to 128 bitów), ale mój umysł Preprocesor C jest trochę flakey. –

+0

OK, w dużej mierze odpowiedziałem na te pytania, które myślę. Mogę * rzucać na długie podwójne i wszystko działa zgodnie z oczekiwaniami. Powyższe odniesienia sugerują, że float128, jeśli istnieje, jest zdefiniowany jako długi podwójny, ale nie jestem tego pewien. –

32

numpy.longdouble odnosi się do dowolnego typu kompilatora C, który wywołuje long double. Obecnie jest to typ zmiennoprzecinkowy z rozszerzoną precyzją z obsługą numpy.

Na x86-32 i x86-64 jest to 80-bit floating point type. W bardziej egzotycznych systemach może to być coś innego (IIRC na Sparc to rzeczywisty 128-bitowy float IEEE, a na PPC to double-double). (To także może zależeć od tego, co system operacyjny i kompilator używasz. - np MSVC na Windows nie obsługuje wszelkiego rodzaju rozszerzonej precyzji w ogóle)

Numpy będzie również eksportować niektóre nazwy jak numpy.float96 lub numpy.float128. Które z tych nazw jest eksportowane, zależy od platformy/kompilatora, ale cokolwiek otrzymasz, zawsze odnosi się do tego samego podstawowego typu, co longdouble. Również te nazwy są bardzo mylące. One nie są wskazują na 96- lub 128-bitowy format zmiennoprzecinkowy IEEE. Zamiast tego wskazują liczbę bitów z linii trasowania wykorzystywanych przez podstawowy typ long double. Np. na x86-32, long double jest 80 bitów, ale jest wyściełane do 96 bitów, aby utrzymać wyrównanie 32-bitowe, i numpy nazywa to float96. Na architekturze x86-64, long double jest ponownie identycznym typem 80-bitowym, ale teraz jest wyściełany do 128 bitów, aby zachować wyrównanie 64-bitowe, a numpy wywołuje to float128. Nie ma dodatkowej precyzji, tylko dodatkowe obicie.

Zalecenie: zignoruj ​​nazwy float96/float128, po prostu użyj numpy.longdouble. Lub jeszcze lepiej trzymać się debla, chyba że masz naprawdę ważny powód. Będą szybsze, bardziej przenośne itp.