C1064: compiler limit: token overflowed internal buffer



  • Hallo,

    ich hab das oben genannte Problem, welches sich an folgender Codestelle äußert:
    real b0 = (6369051672525773.0 / 30191699398572330817932436647906151127335369763331523427009650401964993299137190816689013801421270140331747000246110759198164677039398341060491474011461568349195162615808.0);

    Bei den bis dato getesteten anderen C++-Compilern (Borland, Sun, Gnu, Intel) ist dies kein Problem.
    Der Complier soll während des Compilierungsvorgangs die Konstante berechnen, nicht zur Laufzeit!
    Wenn ich die zweite Zahl kürze (z.B. 301.0E180) übersetzt er die Datei, jedoch
    ist diese Lösung nicht zu gebrauchen.

    Hat jemand eine Idee, wie ich das lösen kann?

    Danke und Gruß

    Boris



  • Hat denn niemand eine Idee?
    Ich habe es heute mit einer hexadezimalen Version probiert, da funktioniert es zwar mit .NET aber nicht mit allen anderen Compilern.



  • Der Fehler ist doch selbstbeschreibend. Deine Zahl/Token ist einfach zu groß. Der interne Buffer für Token ist 128 Zeichen lang. Du kannst außerdem nicht erwarten, dass der Compiler Hochpräzisionsberechnungen für dich übernimmt, für die es selbst keinen Datentyp gibt.

    Was soll real für ein Datentyp sein? Ich kenne real nur als Templatefunktion zum Ermitteln des Realteils einer komplexen Zahl.
    Wieso willst du diese Zahl vom Compiler berechnen lassen? Kannst du es nicht selbst berechnen und mit einer akuraten, für double geeigneten Genauigkeit speichern? Double kann zwar Zahlen mit hohen Zehnerpotenzen aufnehmen, das heißt aber natürlich nicht, dass es dir diese Zahlen mit der vollen Anzahl an gültigen Stellen speichert.

    Das Ergebnis deiner Rechnung ist übrigens

    2.1095373229725999267344748722134329684940683528
    442869376640889454369762513656088668343456516099
    041012053583987571403748750165388048590235665751
    868364245093811246011195272911917752141218674938
    379543111769489610553641383131783938962401846737
    651855729442566909806452857676145754903107669525
    949407047538833530903947782034610818182049497412
    165626624213692994783872614226690779537509712326
    937005855143070220947265625*10^-154

    😉



  • Die Konstante enthält einen Approximations- bzw. Rundungsfehler und ist vom Typ real, dieser ist als Klasse implementiert. Diese Konstante
    ist eine im IEEE-Zahlenformat exakt darstellbare Zahl. Sie muß exakt im Speicher
    abgelegt werden, d.h. es darf bei der Zuweisung kein Rundungsfehler und kein
    Konversionsfehler (von Dezimal- in das Binärsystem) passieren.
    Eine Möglichkeit hierzu, die bisher von allen Compilern korrekt übersetzt wurde,
    ist die Darstellung als Bruch in der Form "Zähler/Nenner". Dabei muß sowohl
    der Zähler als auch der Nenner eine ganz Zahl sein. Der Nenner ist dabei weiter
    eine Potenz zur Basis 2, die Division ist damit fehlerfrei durchführbar (im Binärsystem ist dies lediglich eine Exponentenänderung, die Mantisse wird nicht verändert).
    Die Berechung der Konstanten sollte bei allen modernen Compilern bereits zur
    Übersetzungszeit erfolgen, also nicht später zur Laufzeit eines Programms.

    Dies gilt alles nach dem C++-Standard.

    Das Problem ist also nicht so leicht zu lösen.



  • Woher stammt denn nun der Datentyp real?

    In welche Passage des Standards steht denn, dass der Compiler die Division der Literale wie beschrieben behandeln soll? Theoretisch würde der Compiler ja die Zeile einfach in Token aufteilen, für die jeweils nur ein begrenzter Buffer zur Verfügung steht. Und da das Literal eine zu große Genauigkeit für double hat, wäre es auch nicht erforderlich, einen größeren Buffer zur Verfügung zu stellen. Sollte das Verhalten wirklich so definiert sein, ist der Buffer wohl zu klein geraten 😉



  • Ich meinte, es geht alles nach dem C++-Standard. 😉
    Es handelt sich hier um eine Erweiterung von C++ zum wissenschaftlichen Rechnen. Der Datentyp real ist dort implementiert und besitzt intern ca. 872 Stellen.
    Wie gesagt mit anderen Compilern ist das kein Problem.


Anmelden zum Antworten