% (Teilrest) funktioniert nicht mit double oder float ???



  • cjmischka schrieb:

    danke erst mal Optimizer,
    da das eine Aufgabe für das Studium ist darf ich maximal 32 Bit Ganzzahlentypen benutzen. Gibt es denn noch eine Möglichkeit ?

    wenn so eine einschränkung existiert dann wird es ja wohl auch kaum sinn der sache sein, dass man floats verwendet. vorallem weil die keine ganzzahltypen sind und unter umständen ein datenverlust eintritt. und doubles sind häufig 64 oder gar 80 bit datentypen (auf x86 jedenfalls). ich würd mir das ganze einfach aus zwei 32bittern zusammensetzen. ist zwar ein etwas arbeit, aber durchaus zu machen.



  • Ich bin echt noch neuling was c++ betrifft und kann mir gar nicht vorstellen wie ich das mit 32 bittern zusammensetzen soll ?

    Oh man, ich verzweifle noch an meiner Aufgabe ! Danke für alle hinweise und Tips !



  • Nimm einfach ein int64 und sag, auf einem 32Bit System ist der aus 32-Ints zusammengesetzt. 😃
    Ne mal im Ernst, ich kann mir nicht vorstellen, dass du die nicht benutzen darfst, weil das eine Arbeit fürs Studium ist. Vor allem weil du keine andere Möglichkeit hast, eine Ganzzahl dieser Größe ohne Datenverlust unterzubringen, außer du schreibst dir selber ne Klasse dafür, die mit int32 arbeitet, aber bestimmt nicht schneller ist. 🙄



  • Meine Aufgabe :
    Umwandeln eines Zeichenstrings (eine nichtnegagtive Zahl zur Basis n1) in einen Zeichenstring (dieselbe Zahl zur Basis n2 ), wobei n1,n2 eine der folgenden Zahlen ist :
    10,2,8,32

    der erlaubte Wertebereich beträgt 0...(etwa) 10 hoch 18 - ACHTUNG!

    Hierbei sind Ziffern oberhalb 9 durch Buchstaben A...V oder a...v, d.h. ohne Unterscheidung von Klein und Großschreibung. Sie dürfen davon ausgehen das der eingabewert den gesetzten Bereich nicht überschreitet, ferner dass zur Adresse der Rückgabestrings genügend Speicherplatz vorhanden ist.

    Das Hauptprogramm zum Aufruf und Testen dieser Funktion soll durch Benutzereigabe erhalten: Eingabestring, Basis n1, Basis n2.

    Es ist erlaubt, die rechnerische Dualdarstellung auszunutzen; es ist nicht erlaubt, eine Fließkommadarstellung, z.B. double, zu benutzen, ferner auch keinen 64-Bit-Ganzzahlentyp, Sie dürfen maximal 32-Bit Ganzzahlentypen benutzen.

    ----

    Ich hab mir überlegt das ich sonst alle Werte eines Zeichenstrings in einen anderen packe und die versuche die restwerte in den Folgestring zu übernehemen.



  • cjmischka schrieb:

    der erlaubte Wertebereich beträgt 0...(etwa) 10 hoch 18 - ACHTUNG!
    ...
    Es ist erlaubt, die rechnerische Dualdarstellung auszunutzen; es ist nicht erlaubt, eine Fließkommadarstellung, z.B. double, zu benutzen, ferner auch keinen 64-Bit-Ganzzahlentyp, Sie dürfen maximal 32-Bit Ganzzahlentypen benutzen.

    das ist ja schikanös. sieht aus wie

    typedef unsigned int u32;
    void add(u32 *ch,u32 *cl,u32 ah,u32 al,u32 bh,u32 bl)
    {
       *cl=al+bl;//low digits addieren
       *ch=ah+bh;//high digits addieren
       if(cl<al || cl<bl)//übertrag in low digits ist passiert
          ++*ch;
    
    }
    

    und so auch noch sub, mul und div machen.
    und da man für div 20 stunden braucht, ist die woche bis zur abgabe wiedermal nicht langweilig. 😉
    für mul und div kann es sehr praktisch sein, viel mit & und >> und so zu arbeiten. eben die interne darstellung als dualzahl ausnutzen.
    danach das konvertieren der zahlensysteme ist trivial.



  • Das eine Aufgabe gestellt wird bei der man 20 stunden zum berechen braucht, kann ich mir nicht vorstellen. Da MUSS es einen weg geneb der für anfänger möglich ist !



  • cjmischka schrieb:

    Das eine Aufgabe gestellt wird bei der man 20 stunden zum berechen braucht, kann ich mir nicht vorstellen. Da MUSS es einen weg geneb der für anfänger möglich ist !

    nicht 20 stunden rechnen. 20 stunden programmieren. und zwar 20 stunden für nen anfänger, der in der vorlesung nicht all zu gut aufgepaßt hat, aber wenigstens immer da war.
    ich schaffs natürlich in ner halben stunde, aber nur, weil ich sowas öfters schonmal gemacht hab.



  • oh man. Ich muss sagen darüber seht weder etwas in dem Skrip das und in der Vorlesung kam auch nichts davon dran.

    typedef unsigned int u32;
    void add(u32 *ch,u32 *cl,u32 ah,u32 al,u32 bh,u32 bl)
    {
       *cl=al+bl;//low digits addieren
       *ch=ah+bh;//high digits addieren
       if(cl<al || cl<bl)//übertrag in low digits ist passiert
          ++*ch;
    
    }
    

    Ich versteh auch nicht denn Sinn dieses Quelltextes.



  • Auf welchen Seiten kann ich nach einer möglichkeit, 32 bit Variablen als 64 Bit V. zu nutzen, suchen ? Da muss es doch eine Anleitung einen Source Code oder Hinweise geben.

    Noch mal danke für die Hilfe bis hier hin. 👍



  • Ein unsigned long int ist so groß wie ein signed int64 , jedenfalsl der positive Ast.
    Das Vorzeichen könntest du ja extra speichern.



  • cjmischka schrieb:

    oh man. Ich muss sagen darüber seht weder etwas in dem Skrip das und in der Vorlesung kam auch nichts davon dran.

    ok, alo rechnen wir nicht mit nem selbergebauten 64-bittigen int.
    dann wirds evtl. eher so werden, daß direkt auf den strings gerechnet werden soll.

    //ungetestet und bestimmt falsch, nur ideensammlung
    bool groesser(char* a,char* b)
    {//klappt für jede basis, solange nur a und b in der gleichen basis sind
     //(hoffe ich)
       if(strlen(a)>strlen(b)) return true;
       if(strlen(a)<strlen(b)) return false;
       return strcpy(a,b)<0;
    }
    bool kleiner(char* a,char* b)
    {
       return groesser(b,a);
    }
    bool kleinergleich(char* a,char* b)
    {
       return !groesser(a,b);
    }
    bool istnull(char* a)
    {//ist evtl besser, die zahl 0 als leeren string zu repräsentieren.
       return strlen(a)==0;
    }
    void egalZuDual(char* dual,char* zahl,int basis)
    {
       char* zweierpotenz=new char[100];//lang genug;
       strcpy(zweierpotenz,"1");//"1" ist in jedem zahlensystem 1
       while(kleinergleich(zweierpotenz,zahl))
          verdopple(zweierpotenz,basis);
       //so, jetzt ist in zweierpotenz die kleinste zweierpotenz, die 
       //größer als zahl ist.
       halbiere(zweierpotenz,basis);
       while(!istnull(zweierpotenz))
       {
          if(kleinergleich(zweierpotenz,zahl))
          {
             subtrahiere(zweierpotenz,zahl,basis);
             dual[dualpos]='1';
          }
          else
          {
             dual[dualpos]='0';
          }
          halbiere(zweierpotenz,basis);
       }
    }
    

    öhm. dazu müßte man verdopple(), halbiere() und subtrahiere() programmieren, die jeweils im durch den parameter basis angegebenen zahlensystem rechnen.
    kann das inhalt der vorlesung gewesen sein?

    edit: ausgrechnet 10^18 zu verlangen, klang so deutlich nach 2^64, daß ein selbsgebauter 64-bittiger int so nahe lag. aber ich hab das gefühl, daß direktes rechnen im zielsystem leichter ist, als sich um die 64-bittige division zu kümmern.



  • volkard danke, für deine Mühe. Ich hab jetzt leider nicht ganz deine Idee verstanden. Das liegt aber wahrscheinlich daran das ich heute einfach die schnauze voll hab. Es wurmt mich zwar sehr das ich jetzt kaum einen Schritt weiter mit meinem Programm gekommen bin, jedoch habe ich jede menge dazu gelernt. Ich setze mich morgen wieder dran und hoffe das alles ein wenig besser von statten geht. Bis zum 11.3 habe ich noch Zeit das ganze fertig zu bekommen und ich hoffe mal, dass ich das hinbekomme.



  • unsigned long int ist so groß wie ein signed int64

    Schwachfug, unsigned long int = unsigned long = 32 BIT
    signed int64 = 64 BIT

    MfG MAV



  • Mis2com schrieb:

    Schwachfug, unsigned long int = unsigned long = 32 BIT

    Ach ja? Die Stelle im Standard muss ich übersehen haben.



  • SirLant schrieb:

    Ein unsigned long int ist so groß wie ein signed int64 , jedenfalsl der positive Ast.
    Das Vorzeichen könntest du ja extra speichern.

    Das halte ich für ein Gerücht. Bei mir ist ein long 32 Bit.



  • Ich habe eine Lösung für dich. (Deine Lösungsgedanken waren schon O.K.)Meine Lösung ist bestimmt noch nicht optimal.
    Ausserdem bin ich im Forum hier noch recht neu, falls Code nicht rüberkommt. schicke einfach Mail an Erat0s@aol.com.
    zahl muss long sein, da für dezimalbruch (float, double) Ganzzahldivision nicht definiert ist, Aufruf des Hauptprogrammes (main( ) )im Hauptprogramm bringt nichts. Die Transformierung der Ziffern über 10 stehen bei dir hinter cout und sind damit wirkungslos...

    #include<iostream.h>
    
    main()
    {
    
        long  zahl;
        int syst; 
        int loes;
        char loesout[30];
        int laenge;
        int i; 
        i   =29;
        laenge=0;
    
        cout << "Bitte geben Sie eine Zahl ein:"; 
        cin >> zahl;
    
        do
        {
        	cout << "In welches Zahlensystem (max. 37) soll die Zahl gewandelt werden:";
        	cin >> syst;
        }while( syst>37);
    
        while(zahl>0)
        { 
            loes= (zahl%syst); 
    	zahl= zahl/syst;
    
    	switch(loes)
    	{ 
    	    case 0: loesout[i] ='0'; break;
           	    case 1: loesout[i]= '1'; break; 
                case 2: loesout[i]= '2'; break; 
                case 3: loesout[i]= '3'; break; 
                case 4: loesout[i]= '4'; break; 
                case 5: loesout[i]= '5'; break; 
                case 6: loesout[i]= '6'; break; 
                case 7: loesout[i]= '7'; break; 
                case 8: loesout[i]= '8'; break; 
                case 9: loesout[i]= '9'; break; 
                case 10: loesout[i] = 'A'; break; 
                case 11: loesout[i] = 'B'; break; 
                case 12: loesout[i] = 'C'; break; 
                case 13: loesout[i] = 'D'; break; 
                case 14: loesout[i] = 'E'; break; 
                case 15: loesout[i] = 'F'; break; 
                case 16: loesout[i] = 'G'; break; 
                case 17: loesout[i] = 'H'; break; 
                case 18: loesout[i] = 'I'; break; 
                case 19: loesout[i] = 'J'; break; 
                case 20: loesout[i] = 'K'; break; 
    
                default: cout<<"Fehler in Zeichen" << i<< endl;break; 
    	}
    	i--;
            laenge++;
    
        }
    	cout<< "Die Zahl im "<<syst<<"er System ist:" ;
        for(i=30-laenge;i<30;i++)
        {
    		cout<< loesout[i];
    	}
        cout << endl;
        return(0); 
    }
    

    Bei mir klappt es mit der datei. Wenn Probleme, sende einfach mail an obige Adresse

    Peter

    edit: code-tags eingefügt.



  • So heute c++ Klausur geschrieben und mal gleich meinen Prof darauf angehauenwie ich das Problem den lösen kann. Er schlug vor durch schriftliches Teilen den Teilrest zu ermitteln.

    Ein Studienkollege meinte durch das Hornerschema das Problem zu lösen.

    Ich werde versuchen es erst mal auf diesen Grundlagen zu probieren.

    @ peter55
    danke für deine mühe jedoch läuft das Programm nicht im gewünschten Wertebereich. Es sorgt bei mir nur dafür das die werte der Eingabezahl mit in die zahl des Wertesystems übernommen werden.



  • Optimizer schrieb:

    SirLant schrieb:

    Ein unsigned long int ist so groß wie ein signed int64 , jedenfalsl der positive Ast.
    Das Vorzeichen könntest du ja extra speichern.

    Das halte ich für ein Gerücht. Bei mir ist ein long 32 Bit.

    Hier gelten analoge Beziehungen für char (8 bit).

    unsigned char: -2^7 <= bla < 2^7
    signed char: 0 <= bla < 2^8

    Also gilt für den 32- bit- Datentyp:

    unsigned blubb: -2^31 <= bla < 2^31
    signed blubb: 0 <= bla < 2^32



  • Also eigentlich geht es schon mal damit los, dass die Datentypen in C++ schon mal überhaupt keine feste Größe haben. 🙄
    Aber wenn du willst, können wir von einem 32-Bit System ausgehen. 😃



  • Hallo cjmischka,

    bisst Du noch an Lösung interessiert, oder hat sich das Problem erledigt?

    peter


Anmelden zum Antworten