Array-Werte in einzelne Variablen schreiben


  • Mod

    Schleifen kennst du, oder?



  • na klar kenn ich die, nur weiß ich nicht wie ich der schleife sagen soll, dass sie genau das macht. Mir fehlt es eben an der Syntax bei diesem Problem.

    Nur woher weiss ich, wie lange die schleife zählen muss bevor sie genau da aufhört wo das letzte feld voll ist.

    Und wie bekomme ich synchron die multiplikation mit den einzelnen stellenwerten hin...

    Fragen über Fragen...



  • Mal ab vom Computer.

    Wie machst Du er per Hand?

    Mach mal ein Beispiel vor, möglichst detailliert.



  • securom87 schrieb:

    Die Zahlen stammen aus einer Restwertberechnung, da ich von Dezimal nach Dual Konvertiert habe.

    Zeig mal den Code dafür.

    Groß anders ist die Rückwandlung auch nicht.



  • DirkB schrieb:

    securom87 schrieb:

    Die Zahlen stammen aus einer Restwertberechnung, da ich von Dezimal nach Dual Konvertiert habe.

    Zeig mal den Code dafür.

    Groß anders ist die Rückwandlung auch nicht.

    DirkB schrieb:

    securom87 schrieb:

    Die Zahlen stammen aus einer Restwertberechnung, da ich von Dezimal nach Dual Konvertiert habe.

    Zeig mal den Code dafür.

    Groß anders ist die Rückwandlung auch nicht.

    Hier ist mein Code:

    #define _CRT_SECURE_NO_WARNINGS
    #include <stdlib.h> 
    #include <stdio.h> 
    #include <math.h>  
    #include <string.h>
    #define MAX 8
    
    float buffer = 0;
    int ergvk[MAX], ergnk[MAX];
    int vor = 0, s,i=0, rest=0;
    double nach= 0;
    
    double split(double buffer)
    {
    	double n, v;   n = modf(buffer, &v);						//n nachkommastellen
    
    	return n;
    }
    
    double split2(double buffer)
    {
    	double n, v;   n = modf(buffer, &v);						//v Vorkommastellen
    
    	return v;
    }
    
    void clearBuffer(){												// Eingabepuffer leeren- noch nicht verwendet
    	int buffer;
    	while ((buffer = getchar()) != '\n' && buffer != EOF);
    }
    
    int binarytodecimal();
    
    int main()
    {
    	printf("Bitte eine dezimale Zahl mit Punkt (.) eingeben:");
    	scanf("%f", &buffer);
    
    	vor = split2(buffer);													// Funktionsaufruf Vorkommastellen
    	nach = split(buffer);													// Funktionsaufruf Nachkommastellen
    
    	while (vor != 0) {														// Vorkommastellen in DUAL --> Feld ergvk
    		rest = vor % 2;														
    
    		vor = vor / 2;
    
    		ergvk[s] = rest;
    		s++;
    	}
    	while (nach != 0) {														// Nachkommastellen in DUAL --> Feld ergnk
    		nach = nach * 2;
    		while (nach >= 1.0) {
    			nach = nach - 1;
    			ergnk[i] = 1;
    		}i++;
    	}
    
    		int j = 0;
    		printf("Die dazugehoerige Dualzahl nach der Restwertmethode ist folgende:\n");	
    		for (j = s - 1; j >= 0; j--) {										// Rückwärtsausgabe der Vorkommastelle in Konsole
    			printf("%d", ergvk[j]);
    		}
    		printf("|");														// Ausgabe des Trennzeichens zwischen Vor-und Nachkomma
    		int r = 0;
    		for (r = 0; r < i; r++) {											// Ausgabe der Norkommastelle in Konsole
    			printf("%d", ergnk[r]);
    		}
    		printf("\n");
    
    }
    

    Funktioniert auch alles soweit, nur will ich halt mit der Potenzmethode zurück auf den Ausgangsdeziamalwert kommen können.



  • volkard schrieb:

    Mal ab vom Computer.

    Wie machst Du er per Hand?

    Mach mal ein Beispiel vor, möglichst detailliert.

    Ich würde ein for-schleife bauen, die von feld[0] bis feld[MAX] läuft und jeden darin befindlichen wert, also jede 0 oder 1 ausliest. Und dann müsste ich ja danach die einzelnen ausgelesenen Werte mit dem jeweilige Stellenwert multiplizieren und addieren: also feld[0}*20+feld[1]*21+feld[2]+2^2 usw.
    Diese ganze Rechenoperation müsste ich dann wieder einer INT-Variablen übergeben.

    Nur weiss ich nicht wie ich es schreiben muss 😕

    Gruß und Danke


  • Mod

    Fangen wir mal einfacher an: Bilde die Quersumme der Zahl (d.h. addier alle Stellen). Welchen Code schreibst du dafür?



  • SeppJ schrieb:

    Fangen wir mal einfacher an: Bilde die Quersumme der Zahl (d.h. addier alle Stellen). Welchen Code schreibst du dafür?

    ich habs nun mal anders gemacht:

    habe ne funktion geschrieben binarytodecimal_vk() und einen zeiger übergeben, der auf das erste feld zeigt in dem die binärdaten gespeichert sind, also ergvk[].

    int binarytodecimal_vk(int *pv)
    {
    	int y = 0;
    	int m = 0;
    	for (m = 0; m < countervor; m++){
    		y = (y + (pv[m] * (2 ^ m)));
    	}
    
    	return y;
    }
    

    In dieser Funktion initialisiere ich zwei variablen und steuer anhand von countervor (das ist der zähler der gleichzeitig beim schreiben in das Feld erhöht wird, damit ich weiss wie lange die schleife laufen muss) die schleife.
    Anhand von m sage ich bei jedem durchlauf welches feld über den zeiger im feld ergvk[] angesprochen werden soll und sage meiner berechnung darunter welche potenz die einzelnen Bits haben. Anhand dessen führe ich die Berechnung durch und ordne den jeweils errechneten wert y zu. dieser wird dann auch wieder zurück gegeben.
    Nur stimmt anscheinend mit der rechnung was nicht, da y immer mit 1 übergeben wird und nicht mit 12, wenn ich anfangs 12 eingebe.

    Ich weiss nicht wo der Fehler liegt und bald habe ich keine haare mehr.... 😞

    Hier nochmal der komplette code:

    #define _CRT_SECURE_NO_WARNINGS
    #include <stdlib.h> 
    #include <stdio.h> 
    #include <math.h>  
    #include <string.h>
    #define MAX 8
    
    float buffer = 0;
    int ergvk[MAX], ergnk[MAX];
    int vor,s,i,rest,countervor, counternach=0;
    double nach= 0;
    
    double split(double buffer)
    {
    	double n, v;   n = modf(buffer, &v);						//n nachkommastellen
    
    	return n;
    }
    
    double split2(double buffer)
    {
    	double n, v;   n = modf(buffer, &v);						//v Vorkommastellen
    
    	return v;
    }
    
    void clearBuffer(){												// Eingabepuffer leeren- noch nicht verwendet
    	int buffer;
    	while ((buffer = getchar()) != '\n' && buffer != EOF);
    }
    
    int binarytodecimal_vk(int *pv)
    {
    	int y = 0;
    	int m = 0;
    	for (m = 0; m < countervor; m++){
    		y = (y + (pv[m] * (2 ^ m)));
    	}
    
    	return y;
    }
    
    int main()
    {
    	int *pv = ergvk;
    	int *pn = ergnk;
    
    	printf("Bitte eine dezimale Zahl mit Punkt (.) eingeben:");
    	scanf("%f", &buffer);
    
    	vor = (int) split2(buffer);													// Funktionsaufruf Vorkommastellen
    	nach = split(buffer);													// Funktionsaufruf Nachkommastellen
    
    	while (vor != 0) {														// Vorkommastellen in DUAL --> Feld ergvk
    		rest = vor % 2;														
    
    		vor = vor / 2;
    
    		ergvk[s] = rest;
    		s++,countervor++;
    	}
    	while (nach != 0) {														// Nachkommastellen in DUAL --> Feld ergnk
    		nach = nach * 2;
    		while (nach >= 1.0) {
    			nach = nach - 1;
    			ergnk[i] = 1;
    		}i++,counternach++;
    	}
    
    		int j = 0;
    		printf("Die dazugehoerige Dualzahl nach der Restwertmethode ist folgende:\n");	
    		for (j = s - 1; j >= 0; j--) {										// Rückwärtsausgabe der Vorkommastelle in Konsole
    			printf("%d", ergvk[j]);
    		}
    		printf("|");														// Ausgabe des Trennzeichens zwischen Vor-und Nachkomma
    		int r = 0;
    		for (r = 0; r < i; r++) {											// Ausgabe der Nachkommastelle in Konsole
    			printf("%d", ergnk[r]);
    		}
    		printf("\n");
    
    		printf("Mit >>Enter<< geben wir mit der Potenzmethode die Dezimalzahl wieder aus:");
    		char c;
    		scanf("%c", &c);
    		while (getchar() != '\n');
    
    		printf("%d", binarytodecimal_vk(pv));
    
    }
    


  • Ich hab meine funktion nun nochmal verändert und jeden Rechenschritt einzeln ausgeführt:

    int binarytodecimal_vk(int *pv)
    {
    	int y=0;
    	//int m = 0;
    	//for (m = 0; m < countervor; m++){
    
    		y = pv[0] * 1;
    		y = y + pv[1] * 2;	
    		y = y + pv[2] * 4;
    		y = y + pv[3] * 8;
    		y = y + pv[4] * 16;
    
    		//y = (y + (pv[m] * (2 ^ m)));
    	//}
    
    	return y;
    }
    

    Nun kommt das richtige Ergebnis heraus, nur ich hab absoltut kein Schimmer was an meiner zuvor verwendeten Formel falsch sein könnte 😮


  • Mod

    ^ ist XOR, keine Potenz.



  • SeppJ schrieb:

    ^ ist XOR, keine Potenz.

    Super vielen Dank, das hat mir sehr weiter geholfen 😉

    nun habe ich noch ein letztes problem:

    Hab mir nun noch eine Funktion geschrieben, die mir aus den Dual- Zahlen meine Dezimalzahl wieder heruasgibt:

    double binarytodecimal_nk(int *pn)
    {
    	double z = 0;
    	int n = 0;
    	int a3 = 0;
    	double basis = 2.0;
    	for (n = 0; n <= counternach; n++){
    		a3 = pow(basis, n + 1);
    		z = (z + (pn[n] * (1 / a3)));
    	}
    
    	return z;
    }
    

    Hierbei habe ich nun noch das Problem, dass der Rückgabewert permanent 0 ergibt, wobei ich explizit in der obigen Gleichung doch jede Berechnung der einzelnen Array-Werte mit der dazugehörigen Stellenwertigkeit multipliziere.
    Z bekommt einfach keine Werte zugeordnet.

    hat jemand eine Idee was dort faul ist?

    Dankeschön 🙂


  • Mod

    Wenn du eine ganze Zahl durch eine ganze Zahl teilst, dann kommt auch wieder eine ganze Zahl raus. Das heißt, wenn der Teiler größer ist als das Geteilte, kommt 0 raus.

    Gewöhn dir globale Variablen lieber sofort ab.



  • SeppJ schrieb:

    Wenn du eine ganze Zahl durch eine ganze Zahl teilst, dann kommt auch wieder eine ganze Zahl raus. Das heißt, wenn der Teiler größer ist als das Geteilte, kommt 0 raus.

    Gewöhn dir globale Variablen lieber sofort ab.

    Okay, nur wie kann ich es denn erreichen, dass mir die Funktion eine Kommazahl zurückgibt bzw. eine Zahl die definitiv kleiner ist als 1?

    Weil in der Funktion geht es ja nur um Zahlen kleiner 1.

    Liebe Grüße


  • Mod

    Dazu muss mindestens einer der Operanden in der Division von einem Fließkommatyp sein. Also a3 oder 1 oder beide. Ein Literal vom Typ double mit dem Wert 1 wäre beispielsweise 1.0



  • SeppJ schrieb:

    Dazu muss mindestens einer der Operanden in der Division von einem Fließkommatyp sein. Also a3 oder 1 oder beide. Ein Literal vom Typ double mit dem Wert 1 wäre beispielsweise 1.0

    Also habe a3 mal als double definiert, bringt aber keine Besserung. Der zurückgegebene Wert ist danach immer noch 0.

    Meine Funktion sieht momentan so aus:

    double binarytodecimal_nk(int *pn)
    {
    	double z = 0;
    	int n = 0;
    	double a3 = 0;
    	double basis = 2.0;
    	for (n = 0; n <= counternach; n++){
    
    		a3 = pow(basis, n + 1);
    		z = (z + (pn[n] * (1 /a3)));
    	}
    
    	return z;
    }
    


  • Kommando zurück!!!! z hat sich mittlerweile doch verändert.

    Es hatte anscheinend an den äußersten Klammern gelegen.
    nachdem ich diese entfernt hatte funktionierte es einwandfrei.

    Vielen Dank für diese Hilfestellung! 🙂



  • So vielen Dank nochmal an alle, die mir geholfen haben. Programm funktioniert nun einwandfrei und zu meiner vollsten Zufriedenheit.

    Liebe Grüße 🙂


  • Mod

    Alle deine Klammern sind unnötig, aber eigentlich (bzw. gerade deswegen) sollten sie nichts am Ergebnis ändern. Kannst du mal den Code vorher und nachher zeigen und sagen, was heraus kommt?



  • SeppJ schrieb:

    Alle deine Klammern sind unnötig, aber eigentlich (bzw. gerade deswegen) sollten sie nichts am Ergebnis ändern. Kannst du mal den Code vorher und nachher zeigen und sagen, was heraus kommt?

    Also entweder es lag an den Klammern oder vllt doch eher an der double Definition der Variablen, die an der Berechnung teilnehmen.

    Hier ist nochmal der Code wo es nicht funktioniert hatte und z konstant 0 war:
    Lag wohl wirklich daran, dass der Nachkommateil wegen des INT von a3 immer abgeschnitten wurde.

    double binarytodecimal_nk(int *pn)
    {
        double z = 0;
        int n = 0;
        int a3 = 0;
        double basis = 2.0;
        for (n = 0; n <= counternach; n++){
            a3 = pow(basis, n + 1);
            z = (z + (pn[n] * (1 / a3)));
        }
    
        return z;
    }
    

    Hier nun der Code der funktioniert:

    double binarytodecimal_nk(int *pn)
    {
    	double z = 0;
    	int n = 0;
    	double a3 = 0;
    	double basis = 2.0;
    	for (n = 0; n <= MAX; n++){
    
    		a3 = pow(basis, n + 1);
    		z = z + (pn[n] * (1 /a3));
    	}
    
    	return z;
    }
    

    Liebe Grüße 🙂



  • In deinem ersten Beispiel ist 1/a3 immer 0 für alle a3 die > 2 oder < -2 sind. (Integer-Division, da Dividend und Divisor vom Typ einer Ganzzahl sind)

    Ein 1.0/a3 beseitigt das Problem.


Anmelden zum Antworten