Unterchied zwischen int und long?



  • ~john schrieb:

    Siassei schrieb:

    Ich suche zur Zeit nach einer Möglichkeit, die zweite Methode Compiler unabhängig umzusetzen. Wie ermittle ich hierfür einen geeigneten Datentyp?

    Über welche Plattform reden wir hier: Windows oder eines der OS die die SUS erfüllen?

    Vorraussetzung für meine Antwort: SUS

    Unter anderem. Ich persönlich würde es gerne auf die gängigen Plattformen portieren können. Sprich Windowx XP und Vista, Linux (SuSe, Ubuntu, RedHat, ...), MacOS, HP-UX und Solaris.



  • Siassei schrieb:

    Intressanter Beitrag 😉

    Ich versuche seit ein paar Tagen eine Integer-Klasse zu erstellen, die theoretisch unendlich lange Zahlen darstellen kann. Bei den Rechenoperationen gibt es nun zwei Möglichkeiten Pufferüberläufe zu verhindern.

    1.) Ich benutze das letzte Bit des Types (z.B. int) nicht
    2.) Ich stelle die Zahlen in z.B. 32bit dar und rechne in (32 * 2)bit.

    Ich suche zur Zeit nach einer Möglichkeit, die zweite Methode Compiler unabhängig umzusetzen. Wie ermittle ich hierfür einen geeigneten Datentyp?
    z.B: int (32bit), long (64bit)

    Eine hab ich noch 😃 Wenn bei 64bit Systemen int 32bit und long 64bits bestitzen, wie viele Bits besitzt eine long long Deklarierung?

    Servus,

    programmieren ist mein Hobby und ich würde dieses Problem sehr gerne lösen 🙂 Ich hab mir jetzt mal die Manuals zum gcc rein gezogen. Leider stieß ich hier auf keine geeigneten Lösungsmöglichkeit.

    Hat von euch jemand einen Ansatz?


  • Administrator

    Bist du dazu nicht ein wenig im falschen Thread?
    Naja, ich habe mir so eine riesen Integer Zahl mittels BCD (Binary Coded Decimal) gelöst. Könntest mal dazu suchen gehen oder hier nachschauen:
    http://en.wikipedia.org/wiki/Binary_Coded_Decimal

    Grüssli



  • Ich hoffe nicht 😉

    Wenn ich int bzw. long verwende arbeite ich indirekt mit dem Binary-Code der Dezimalzahlen.

    OK. In <limits> kann ich die Länge von int und long ermitteln. Eine Frage habe ich aber noch 😃 Wie kann ich den Compiler abbrechen, wenn die Bedingung

    ( numeric_limits<int>::digits == numeric_limits<long>::digits ) || ( (numeric_limits<long>::digits - numeric_limits<int>::digits  ) < numeric_limits<int>::digits  )
    

    erfüllt ist?



  • Mit #error kann man einen Fehler auslösen.

    Bei den numeric_limit -Sachen musst du aber aufpassen. Eventuell wird das Ergebnis (z.B. von Funktionen) noch nicht zur Compilezeit ausgewertet, im nächsten C++-Standard geht das erst (mit constexpr )...



  • Und selbst wenn's konstant wäre würde dir #error nichts bringen, das ist der Präprozessor.
    Das Zauberwort heißt static_assert , gibt's aber auch erst im nächsten Standard. Du kannst dafür Boost.StaticAssert verwenden oder dir flugs dein eigenes zusammenhacken:

    template <bool Val>
    struct static_assert {};
    
    template <>
    struct static_assert<false>;
    

    /edit: Zu viel Python in letzter Zeit



  • Wieso würde #error nicht gehen, wenn der Ausdruck compiletime-konstant wäre? Kombiniert mit #if kann man dann eine Abfrage machen...

    Siassei wollte ja den Compiler abbrechen.



  • #error und #if sind Präprozessorausdrücke. Das heißt, das Ganze wird vor dem Kompilieren abgearbeitet. Bei den meisten Compilern ist der Präprozessor sogar ein gesondertes Programm. Konsequenz davon ist, dass er keine C++-Ausdrücke auswerten kann (auch nicht, wenn sie compilezeit-konstant sind), der Präprozessor sieht nur den String, sonst nichts.

    /edit: Und genau der Compiler wird mit einem static_assert auch abgebrochen, nicht aber der Präprozessor 😉



  • Okay, da ist mir wohl ein Denkfehler unterlaufen 😉

    Andere Frage: Wie kann man den Compiler abbrechen? Also wie soll eine eigene Implementation eines static_assert aussehen?



  • Siassei schrieb:

    Unter anderem. Ich persönlich würde es gerne auf die gängigen Plattformen portieren können. Sprich Windowx XP und Vista, Linux (SuSe, Ubuntu, RedHat, ...), MacOS, HP-UX und Solaris.

    Waum nimmst Du nicht int64_t & Co. aus "stdint.h" bzw. "inttypes.h"?
    Desweiteren gibt es Makros, die in der SUS definiert werden, mit denen man testen kann welche Umgebung vorhanden ist. Zu Windows kann ich mich nicht äußern.

    #include <ostream>
    #include <iostream>
    
    #include <unistd.h>
    #include <inttypes.h>
    
    using namespace std;
    
    int main () {
    
    #if _XBS5_ILP32_OFF32 || _XBS5_ILP32_OFFBIG || _XBS5_LP64_OFF64 || _XBS5_LPBIG_OFFBIG
    	cout << "_XBS5_* legacy Makros definiert\n";
    #endif
    
    #if _POSIX_V6_ILP32_OFF32 || _POSIX_V6_ILP32_OFFBIG || _POSIX_V6_LP64_OFF64 || _POSIX_V6_LPBIG_OFFBIG
    	cout << "_POSIX_V6_* Macros definiert\n";
    #endif
    
    #if _POSIX_V6_ILP32_OFF32 || _XBS5_ILP32_OFF32
    	cout << "int, long, pointer und off_t sind 32bit\n\n";
    #elif _POSIX_V6_ILP32_OFFBIG || _XBS5_ILP32_OFFBIG
    	cout << "int, long und pointer sind 32bit, off_t ist mindestens 64bit\n\n";
    #elif _POSIX_V6_LP64_OFF64 || _XBS5_LP64_OFF64
    	cout << "int ist 32bit, long, pointer und off_t sind 64bit\n\n";
    #elif _POSIX_V6_LPBIG_OFFBIG || _XBS5_LPBIG_OFFBIG
    	cout << "int ist 32bit, long, pointer und off_t sind mindestens 64bit\n\n";
    #else
    	cout << "Makros nicht definiert!\n\n";
    #endif
    


  • Nexus schrieb:

    Andere Frage: Wie kann man den Compiler abbrechen? Also wie soll eine eigene Implementation eines static_assert aussehen?

    Steht doch in meinem Posting?!

    Das ist die Minimalvariante. Der Trick ist, dass die Templatespezialisierung für static_assert<false> absichtlich nicht implementiert wird. Instanziiert man dann das Template bricht der Compiler ab.



  • Ah, das reicht schon. Ich dachte, da gehöre noch mehr dazu, danke 🙂



  • ~john schrieb:

    Siassei schrieb:

    Unter anderem. Ich persönlich würde es gerne auf die gängigen Plattformen portieren können. Sprich Windowx XP und Vista, Linux (SuSe, Ubuntu, RedHat, ...), MacOS, HP-UX und Solaris.

    Waum nimmst Du nicht int64_t & Co. aus "stdint.h" bzw. "inttypes.h"?
    Desweiteren gibt es Makros, die in der SUS definiert werden, mit denen man testen kann welche Umgebung vorhanden ist. Zu Windows kann ich mich nicht äußern.

    Wie du vielleicht schon festgestellt hast, arbeite ich mich gerade in C bzw. C++ ein. Die Typen int64_t, ... kannte ich noch nicht, aber wusste bereits dass es irgendwo solche gibt 😉

    Da ich nur so zum Spass programmiere und das ganze ein Hobby von mir ist, versuche das über die "primitiven" Typen zu implementieren. Zudem gibt es hier wohl den höchsten Lerneffekt bzw. -stoff.
    Was habe ich vor? Ich möchte für die natürlichen, ganze (mit Signum), rationalen, dezimalen sowie komplexe Zahlen eine Klasse erstellen. Sie sollen jeweils alle Zahlen darstellen können, solange mir C++ keine OutOfMemoryException oder so was ähnliches liefert 😃 Zudem plane ich bei der Dezimalklasse eine intelegente Folgenerekennung z.B. für 0,333.. bei 1/3.



  • Siassei schrieb:

    Ich möchte für die natürlichen, ganze (mit Signum), rationalen, dezimalen sowie komplexe Zahlen eine Klasse erstellen.

    Das kommt mir irgendwie bekannt vor... So aus Freude kann man das ja schon machen, aber damit programmieren solltest du damit besser nicht (die komplexen Zahlen mal ausgenommen). Abgesehen von eventuellen Performancenachteilen kannst du viele Funktionen nicht auf die eigenen Klassen anwenden. Was bezweckst du damit? Und wieso reichen Elementartypen nicht?

    Siassei schrieb:

    Zudem plane ich bei der Dezimalklasse eine intelegente Folgenerekennung z.B. für 0,333.. bei 1/3.

    Wie meinst du das genau? Dass er bei einem double -Wert 0.33333 erkennt, dass es 1/3 darstellen soll? Das wird wahrscheinlich nicht gerade einfach und du hast immer nur Approximationen...



  • Nexus schrieb:

    Siassei schrieb:

    Ich möchte für die natürlichen, ganze (mit Signum), rationalen, dezimalen sowie komplexe Zahlen eine Klasse erstellen.

    Das kommt mir irgendwie bekannt vor... So aus Freude kann man das ja schon machen, aber damit programmieren solltest du damit besser nicht (die komplexen Zahlen mal ausgenommen). Abgesehen von eventuellen Performancenachteilen kannst du viele Funktionen nicht auf die eigenen Klassen anwenden.

    Und? An meinem Laptop sitzt nur ich und ob eine Rechnung 5ms oder 0,1 ms dauert ist mir vollkommend egal 😉 Ich möchte mich nur eingehend mit der C++ Sprache befassen und hab als Projekt eine kleine Leidenschaft gewählt 😃

    Siassei schrieb:

    Zudem plane ich bei der Dezimalklasse eine intelegente Folgenerekennung z.B. für 0,333.. bei 1/3.

    Wie meinst du das genau? Dass er bei einem double -Wert 0.33333 erkennt, dass es 1/3 darstellen soll? Das wird wahrscheinlich nicht gerade einfach und du hast immer nur Approximationen...

    Nun, ich hab mich wohl etwas ungestümt ausgedrügt. 1/3 kann ich in der Dezimalschreibweise auf zwei verschiedenen Arten darstellen:
    1.) Gerundet z.B. 0,3333
    2.) mit einer Periodenkennzeichnung z.B. 0,3 wobei ich über die 3 einen Strich zeichne

    Und eben das ist die große Schwäche von Fließkommazahlen. Ich bekomme bei jeder Rechnung einen Rundungsfehler, sowie einen Fehler durch die Mantisse und Exponenten, aber das weißt du eh. Performance ist halt nicht alles 😉



  • Okay, ja zum Rumspielen und Lernen ist das wie gesagt schon okay... Es gibt drum Leute, die wollen so was ernsthaft durchziehen 🙂

    Siassei schrieb:

    Und eben das ist die große Schwäche von Fließkommazahlen. Ich bekomme bei jeder Rechnung einen Rundungsfehler, sowie einen Fehler durch die Mantisse und Exponenten, aber das weißt du eh. Performance ist halt nicht alles 😉

    Dann würde ich dir raten, eine Bruchklasse zu schreiben. Dann kannst du exakt mit rationalen Zahlen rechnen. Und für reelle kannst du immer noch Näherungen nehmen, ungenau ist es dann so oder so.

    So eine Klasse hab ich kürzlich auch geschrieben und ich fands noch lustig 😉


Anmelden zum Antworten