Integer-Potenzierung in OCaml

9

Gibt es eine Funktion für Integer-Potenzierung in OCaml? ** ist nur für Schwimmer. Obwohl es meistens genau zu sein scheint, gibt es keine Möglichkeit für Präzisionsfehler, etwa 2. ** 3. = 8. manchmal falsch? Gibt es eine Bibliotheksfunktion für die Integer-Potenzierung? Ich könnte mein eigenes schreiben, aber das bringt Effizienzprobleme mit sich, und ich würde mich auch wundern, wenn es nicht schon eine solche Funktion gibt.

    
user2258552 05.06.2013, 22:03
quelle

3 Antworten

10

In Bezug auf den Fließkommateil Ihrer Frage: OCaml ruft die Funktion pow() des zugrunde liegenden Systems auf. Fließkomma-Exponentiation ist eine schwierige Funktion, die implementiert werden muss, aber sie muss nur treu sein (das heißt genau auf eine Einheit am letzten Platz ), damit 2. ** 3. = 8. zu true ausgewertet wird, weil 8.0 das einzige float innerhalb einer ULP des mathematisch korrekten Ergebnisses 8 ist.

Alle Mathematikbibliotheken sollten (*) treu sein, also sollten Sie sich über dieses spezielle Beispiel keine Sorgen machen. Aber nicht alle von sie sind eigentlich , also hast du recht, wenn du dir Sorgen machst.

Ein besserer Grund zur Sorge wäre, wenn Sie 63-Bit-Ganzzahlen oder breiter verwenden, dass die Argumente oder das Ergebnis der Potenzierung nicht genau dargestellt werden können, wenn OCaml schwebt (tatsächlich IEEE 754-Zahlen mit doppelter Genauigkeit, die nicht% repräsentieren können) co_de% oder 2 53 + 1). In diesem Fall ist die Fließkomma-Potenzierung ein schlechter Ersatz für die Potenzierung von Ganzzahlen, nicht wegen einer Schwäche in einer bestimmten Implementierung, sondern weil sie nicht dafür ausgelegt ist, genau so große Ganzzahlen darzustellen.

(*) Eine weitere unterhaltsame Referenz zu diesem Thema ist " Ein Logarithmus zu clever um die Hälfte "Von William Kahan.

    
Pascal Cuoq 06.06.2013, 11:37
quelle
19

Nicht in der Standardbibliothek. Sie können aber auch einfach selbst eine schreiben (mit Potenzierung durch Quadrieren , um schnell zu sein) oder eine erweiterte Bibliothek, die dies bietet, wiederverwenden. In Batterien ist Int.pow .

Unten ist eine vorgeschlagene Implementierung:

%Vor%

Wenn das Risiko eines Überlaufs besteht, weil Sie sehr große Zahlen manipulieren, sollten Sie wahrscheinlich eine Big-Integer-Bibliothek wie verwenden Zarith , der alle möglichen Potenzierungsfunktionen bietet.

(Sie benötigen möglicherweise die "modulare Potenzierung", Berechnung (a^n) mod p ; dies kann so erfolgen, dass Überläufe vermieden werden, indem der Mod in den Zwischenberechnungen angewendet wird, z. B. in der obigen Funktion pow .)

    
gasche 05.06.2013 22:07
quelle
3

Hier ist eine andere Implementierung, die Potenzierung durch Quadrieren verwendet (wie die von @gashche), aber diese ist tail-recursive

%Vor%     
Halst 12.05.2016 10:33
quelle