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.
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.
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
.)
Tags und Links integer ocaml floating-accuracy exponentiation