lange doppelte Rückkehr und Ctypes

9

Ich habe eine c-Funktion, die ein long double zurückgibt. Ich möchte diese Funktion von Python mit Ctypes aufrufen, und es funktioniert meistens. Das Setzen von so.func.restype = c_longdouble macht den Trick - außer dass der Float-Typ von python ein c_double ist. Wenn also der zurückgegebene Wert größer als ein double ist, aber innerhalb der Grenzen eines langen double, erhält Python trotzdem inf als Rückgabewert. Ich bin auf einem 64-Bit-Prozessor und sizeof(long double) ist 16.

irgendwelche Ideen um dies zu umgehen (z. B. mit der Dezimalklasse oder numpy) ohne den c-Code zu ändern?

    
Autoplectic 08.01.2009, 06:00
quelle

3 Antworten

1

Ich bin mir nicht sicher, ob Sie das tun können, ohne den C-Code zu ändern. ctypes scheint wirklich schlechte Unterstützung für long double s zu haben - Sie können sie nicht wie Zahlen manipulieren, Sie können sie nur zwischen dem nativen float Python-Typ hin und her konvertieren.

Sie können nicht einmal ein Byte-Array als Rückgabewert anstelle von c_longdouble verwenden, da die ABI-Gleitkommawerte nicht wie die normalen Rückgabewerte im %eax -Register oder im Stapel zurückgegeben werden Sie werden durch die hardwarespezifischen Gleitkommaregister geleitet.

    
Adam Rosenfield 08.01.2009, 06:56
quelle
1

Wenn eine Funktion eine Unterklasse von c_longdouble zurückgibt, gibt sie das umschlossene ctypes-Feldobjekt zurück und konvertiert nicht in ein Python float . Sie können dann die Bytes daraus extrahieren (zB mit memcpy in ein Array c_char) oder das Objekt zur weiteren Verarbeitung an eine andere C-Funktion übergeben. Die Funktion snprintf kann sie in eine Zeichenfolge zum Drucken oder Konvertieren in einen hochpräzisen numerischen Python-Typ formatieren.

%Vor%

Ausgabe:

%Vor%

(Beachten Sie, dass meine Schätzung von 35 Stellen der Genauigkeit für long double Berechnungen auf Intel Prozessoren, die nur 64 Bit Mantisse haben, zu optimistisch ist. Sie sollten %a anstatt %e /% co_de verwenden % / f , wenn Sie in ein Format konvertieren möchten, das nicht auf Dezimaldarstellung basiert.)

    
Random832 11.03.2015 18:21
quelle
0

Wenn Sie einen hochpräzisen Fließkommawert benötigen, sehen Sie sich GMPY an.

GMPY ist ein C-codiertes Python-Erweiterungsmodul, das die GMP-Bibliothek umschließt, um Python-Code für schnelle Multipräzisionsarithmetik bereitzustellen (Integer, Rational und Float), Generierung von Zufallszahlen, erweiterte zahlentheoretische Funktionen und mehr.

GMP enthält Fließkomma-Arithmetikfunktionen auf hoher Ebene ( mpf ). Dies ist die GMP-Funktionskategorie, die verwendet werden soll, wenn der C-Typ "double" nicht genügend Genauigkeit für eine Anwendung bietet. Es gibt ungefähr 65 Funktionen in dieser Kategorie.

    
gimel 08.01.2009 07:08
quelle

Tags und Links