Modernes C++ programmieren

Apr 03, 2012

Mit C++11 hört C++ nicht auf -- unbounded-precision integer types

Mit der Verabschiedung von C++11 gibt sich die Gemeinde natürlich nicht zufrieden. Auch C++ wird sich natürlich noch weiter entwickeln. Einige Dinge wurden aus C++0x herausgelassen, damit “0x” es letztendlich wenigstens “11” werden konnte. Man wird aber sicher alte Bekannte irgendwann wiedersehen.

Dazu gehören zuvorderst natürlich die Concepts, aber viele erwarten auch Asynchrone IO oder Filesystem- und Dateinamenbehandlung – oder irgendetwas aus dem Umfeld von Boost.

C++1y, TR, oder Papierkorb

Was in den Standard Einzug halten wird, ob wann, oder ob es einen Nachtrag oder Technical Report mit Erweiterungen geben wird, steht natürlich in den Sternen. Nein, nicht in den Sternen – man kann sich an den Diskussionen ja beteiligen und vielleicht deren Ausgang ein wenig beeinflussen. Für den Interessierten lohnt es sich also, die Augen offen zu halten…

Es tut sich viel, aber ich greife mal exemplarisch etwas heraus…

integer und unsigned_integer

Neu in der Diskussion ist eine kleine aber feine Erweiterung für Ganzzahlen mit unbegrenzter Genauigkeit. “Unbegrenzt” meint hier dynamisch unbegrenzt, im Vergleich zu statisch unbegrenzt. Es wäre ein wenig leichter, zum Beispiel einen Zahltypen zu definieren, bei dem man bei der Initialisierung eine maximale Länge angeben muss – überschreitet man die, gäbe es einen Überlauf. Statt aber die Klasse integer auf einer Art festem Array zu basieren, schwebt den Autoren von N3375 konzeptionell eher ein vector vor. So kann kein Überlauf mehr passieren, die Größe passt sich automatisch an – bis der Speicher ausgeht…

Da gibt es natürlich schon jede Menge Bibliotheken (zum Beispiel die vielseitige Gnu GMP) , aber die wenigsten schmecken nach C++11.

Mit den bestehenden Zahlentypen wird integer natürlich interagieren. Die arithmetischen wie +, * und Verwandte werden mit sich selbst und int-Varianten unterstützt.

    integer i = 30000;
    integer j = 1000 * i;

Allerdings geschieht dies im aktuellen Vorschlag nicht durch Überladung von operator+() etc mit allem möglichen int -Varianten, sondern durch die implizite Umwandlung von int in integer.

Der aktuelle Vorschlag bietet:

  • arithmetische Operationen +, -, *, /, %, – und ++
  • eine Funktion div(), die gleichzeitig das ganzzahlige Ergebnis und den Rest zurückgibt,
  • Bitoperationen |, &, \^, \<\<, >>, \<\<=, >>=, |=, &= und\^=.
  • Vergleiche ==, \<, >, !=, \<= und >=
  • Quadrat, Quadratwurzel sowie `sqrtrem()` um gleichzeitig Quadratwurzel und Rest zu erhalten
  • Exponenzieren mit pow(), bzw. powmod() – letzterest ist ein häufiger Anwendungsfall, der eine platzsparendes pow() gefolt von einer Modulo-Operation ist. Den GGT und KGV kann man mit gcd() und lcm() berechnen.
  • Eine beliebig lange Zufallszahl kann man erstellen,
  • Stream-Ein- und Ausgabe wird unterstützt; mit `to_string(base=10)` ist ebenfalls praktisch.

Noch Offen

Chancen sich einzubringen hat man vielleicht insbesondere bei den noch offenen Punkten des aktuellen Vorschlags:

  • Wie soll die Speicherverwaltung duch den Benutzer beeinflußt werden können? Wie sollen Allocators Eingang finden?
  • Was soll passieren bei einem Unterlauf, zum Beispiel bei
    • unsigned_integer neg = -99;?
    • unsigned_integer five = 5 und dann unsigned_integer result = five - 100?
    • unsigned_integer five = 5; unsigned_integer ten = 10, dann five - ten?
  • Wie ist mit Präzisionsverlust umzugehen, wenn ein sehr großer integer in einen int umgewandelt werden soll?

Wer hat Vorschläge?

Links

N3375 - Proposal for Unbounded-Precision Integer Types