2016-03-29 6 views
1

Dies ist eine Hausaufgabenfrage. In SML gibt es eine Grenze für Integer-Größe, die Int.maxInt ist, also muss ich ein Paket entwerfen, das große Ganzzahlen darstellen kann und Operationen wie Addieren, Multiplizieren usw. ausführen kann. Jetzt ist die offensichtliche Wahl, sich in a aufzuteilen Liste oder Array, wo jedes Element eine ganze Zahl von akzeptabler Größe hat. Aber definieren, wenn eine Funktion annehmen,SML: Modul für große Integer-Darstellung

IntToLargeInt(x, base) = (x mod base) :: IntToLargeInt(x div base , base) 

Nun, für ganze Zahlen kleiner als die maximalen Größe, ist es zu einer Reihe von anderer Basis in einer Liste zu konvertieren. Aber mit großen Ganzzahlen, bevor es sogar aufteilen kann, löst es eine Überlauf-Ausnahme aus. Also, irgendein Hinweis, wie man vom Funktionsargument direkt wie ein stdin-Stream oder etwas Ähnliches analysieren kann. Im Grunde alles, was mir hilft, die Funktion für große Ganzzahlen arbeiten zu lassen.

Sollte ich Typen wie IntInf zuerst speichern und dann zu einer anderen Basis konvertieren?

Oder vielleicht, wenn ich in die falsche Richtung gehe, wären einige Hinweise darüber, wo ich anfangen soll, gut.

Antwort

1

Wenn Sie über die Effizienz besorgt sind, kann es sinnvoll sein, IntInf.fromString zu verwenden. Aber - wenn Sie sich wirklich Gedanken über die Effizienz machen würden, dann würden Sie einfach IntInf für alles verwenden und nicht versuchen, eine große Zahlenbibliothek selbst zu implementieren.

Eine naivere Methode besteht darin, eine Ziffernfolge in eine umgekehrte Ziffernliste zu zerlegen und diese Ziffernliste in eine Ihrer int-Listen umzuwandeln. Sie können dies tun, so schnell wie möglich:

1) Konvertieren einzelne Ziffern in LargeInts

2) Multiplizieren Sie Ihre LargeInts von 10

3) hinzufügen LargeInts

eine Vorstellung zu bekommen, wie dies eine Implementierung einer Funktion, die einen String in eine gewöhnliche ganze Zahl konvertiert funktionieren könnte, ist hier:

fun digitToInt d = Char.ord d - Char.ord #"0"; 

fun digitsToInt [] = 0 
| digitsToInt (d::ds) = digitToInt d + 10 * digitsToInt ds; 

Hinweis , dass die + und * in den oben genannten müssten durch Ihre benutzerdefinierten Funktionen ersetzt werden. Das oben Gesagte gilt für Ziffern, in denen die niedrigstwertige Ziffer an erster Stelle in der Liste steht. Dies ist leider das Gegenteil der Standardmethode, mit der Zahlen dargestellt werden. Wir können die eingebaute Funktion rev verwenden diese zu beheben:

val stringToInt = digitsToInt o rev o explode; 

(. Diese vollständig entspricht

fun stringToInt s = digitsToInt(rev(explode s)); 

aber etwas besser lesbar)

Zum Beispiel

- stringToInt "12345"; 
val it = 12345 : int 

Nicht sehr aufregend, aber Sie sollten in der Lage sein, diesen Ansatz zu ändern, um yo zu entsprechen Deine Situation.

+0

Ich werde den oben genannten Ansatz ausprobieren. Aber wenn ich dann ein ganzes Paket umsetzen muss, was ist der beste Weg? Gibt es Tutorials? –

+0

Nicht ganz sicher, was Sie mit "ein ganzes Paket" meinen, da "Paket" kein SML-Begriff ist."Struktur" ist, aber ich vermute, dass Ihre Hausaufgaben bescheidener sind als eine vollwertige Struktur zu implementieren und stattdessen eine Sammlung von Funktionen zu schreiben, die es Ihnen ermöglicht, einfache Arithmetik für große ganze Zahlen zu machen. Das Darstellen solcher Dinge wie Listen von Ints ist natürlich (was durch einen Typ def abstrahiert werden kann, wenn Sie möchten). Angesichts dieser Darstellung sind Addition, Subtraktion und naive Multiplikation ziemlich einfach. Für die Potenzierung - verwende Potenzierung durch Quadrieren, die ein natürliches rekursives def. –

+0

Ihr Fragentitel enthält das Wort "Modul", was darauf hindeutet, dass Sie möglicherweise eine Struktur implementieren müssen. Selbst dann ist der natürliche Weg zu gehen, zuerst eine Sammlung von einzelnen Funktionen zu erstellen, um die Arithmetik auf Ihren großen Ints zu tun, sie zu Strings, Strings usw. umzuwandeln und sie dann später in eine Struktur zu verpacken. –