Komisches Verhalten in der Matrix



  • Hey, ich hab hier ein kleines Problem mit meiner Matrix/Zweidimensionalen Array.
    Ich weiß nicht ob das jemandem etwas sagt, aber das ganze ist ein Auszug aus einem Programm für die "Streifenmethode des Archimedes", Integralrechnung und so ne...
    Erstmal den Code, dann die Erklärung:

    #include <stdio.h>
    #include <stdlib.h>
    
    int main(int argc, char *argv[])
    {
    	float Wertetabelle[20][2];
    	float Unterteilungsstellen=0;
    	float Streifenbreite=0.2;
    	float Gesamtbreite=2;
    	int Counter=0;
    	int x=1;
    	int y=0;
    	for(Unterteilungsstellen=0; Unterteilungsstellen<=Gesamtbreite; Counter++&&x++)
    	{
    		Wertetabelle[x][y]=Unterteilungsstellen;
    		printf("Unterteilungsstellen: %.2f\n",Unterteilungsstellen);
    		printf("	     Counter: %d\n",Counter);
    		printf("	 Werteintrag: %.2f\n\n",Wertetabelle[x][y]);
    		Unterteilungsstellen+=Streifenbreite;
    	}
    	printf("Endgueltiger Counter Wert: %d\n\n",Counter);
    	for(y=0; y<2; y++)
    	{
    		for(x=0; x<Counter; x++)
    		{
    			printf("  %.2f",Wertetabelle[x][y]);
    		}
    		printf("\n");
    	}
    	printf("\n%.2f\n",Wertetabelle[0][0]);		//Nur zum Test ob der richtige Wert hineingeschrieben wurde
    	system("PAUSE");
    	return 0;
    }
    

    Also was ist das Problem/untypisches Verhalten:
    Zum einen bin ich leicht verwirrt, was den x-Wert in der Wertetabelle[x][y] betrifft. Denn nach meinen bisherigen Kenntnissen hat z.B. die Matrix Wertetabelle[20][2] 20 Felder in x- und
    2 Felder in y-Richtung, aber um einen Wert in das linkere obere Feld einzutragen, muss man Wertetabelle[0][0] nehmen weil eben die 0 auch eine Zahl ist.
    Wenn ich jetzt in Zeile 11 für x eine 0 eintrage passiert folgendes: Er schreibt mir den ersten Wert, also Unterteilungsstellen=0 gar nicht erst rein, sondern schreibt 0.5 in
    Wertetabelle[0][0] hinein. Das bedeutet also eigentlich, dass aus irgendeinem Grund die Anweisung in Zeile 19 ausgeführt wurde --> Unterteilungsstellen (hier 0) + 0.5. Oder das
    Wertetabelle[0][0] gar nicht existiert und deswegen auch nicht eingetragen bekommt, denn bei x=1 ist die vermeintliche Stelle Wertetabelle[0][0] mit einer 0 gefüllt...das kann aber auch
    daran liegen, dass beim printf() Befehl für die Matrix alle Felder die keinen Wert besitzen automatisch mit einer 0 gefüllt werden, was wiederum bedeutet, dass durch x=1 in
    Wertetabelle[0][0] gar nix eingetragen wurde und in der for-Schleife tatsächlich die Anweisung in Zeile 19 vorher ausgeführt wurde... 😕

    Das andere untypische Verhalten ist ungefähr genauso seltsam:
    Zeile 8, die Definition der Streifenbreite, ist eigentlich eine mathematische Rechnung: Die Gesamtbreite (hier 2) geteilt durch die Anzahl der Streifen. Sobald die Anzahl der Streifen 10
    beträgt, die Gesamtbreite bleibt gleich (2), beträgt die Streifenbreite 0.2 und dann taucht das Problemchen auf. Er schreibt den letzten Wert der Unterteilungsstellen in der for-Schleife
    nicht in in die Wertetabelle hinein. Der fehlt einfach OBWOHL im printf() Befehl für die Wertetabelle dieses Feld ausgegeben wird, es steht halt einfach eine 0 drin. Und das passiert mit
    ALLEN Werten, wo die Streifenanzahl >=10 ist, sprich die Streifenbreite <=0.2. 😕

    Das alles ist etwas schwer zu erklären, ich hab das jetzt so gut wie möglich probiert, tut mir Leid. 😕
    Trotzdem bin ich mit meinem C-Latein am Ende und finde den Fehler einfach nicht.



  • Bevor ich jetzt versuche, deine Erläuterung zu verstehen:

    Counter++&&x++
    

    macht nicht dass, was du vermutest (Increment von Counter und x).
    Lass dir mal in der Schleife auch das x ausgeben.

    Statt des logischen UND (&&) muss da ein Komma hin.



  • Okay, Problem Nummer eins ist gelöst. Ich liebe dich ❤
    Btw: verwünscht sei hiermit dieses Tutorial. http://www.c-programmieren.com/C-Lernen.html

    Bleibt nur noch das zweite Problem mit den Werten über 10.



  • Der Rest sollte unter Rundungsfehler laufen.

    Die Genauigkeit von Fließkommazahlen ist begrenzt.

    Im Dezimalsystem kennst du sicher das Problem mit mit 1/3 (0,3333333333333) oder 1/9 (0,11111111)
    Im Binärsystem ist 0,2 auch so eine Zahl

    Hinauszögern kannst du das Problem, indem du double statt float nimmst
    Umgehen kannst du das, indem in der for-Schleife das x (als Ganzzahl) zählst und daraus die Werte berechnest.



  • Ich hab das jetzt kurz mit double getestet, bringt leider nicht viel bis gar nix. Selbst mit long double ist keine veränderung sichtbar (ja ich habe auch alles in %lf geändert).

    Jetzt muss ich nochmal nachfragen, wie genau ist das mit dem x gemeint? :S



  • Und nochmal zum logischen UND.

    Da gilt die Kurzschlußregel. Wenn das erste Argumet schon zur Bestimmung des Ergebnis reicht, wird das zweite Argument nicht mehr ausgewertet.

    Bei dir ist Counter 0. Und 0 && irgendwas bleibt 0.
    Im zweiten Durchlauf sieht das dann schon anders aus.

    Es würde hier funktioniern, wenn du Preincrement nimmst ++Counter&&x++ .
    Aber richtiger und besser lesbar wird es dadurch auch nicht.

    Btw: Es gibt keine guten (deutschen) Online-Tutorials für C.



  • for(x=0; x<20; x++, Counter++)
        {
            Unterteilungsstellen = x / (double)20 *  4.0;  // 20  Werte im Array und  20 * 0.2 = 4.0
    
            Wertetabelle[x][y]=Unterteilungsstellen;
            printf("Unterteilungsstellen: %.2f\n",Unterteilungsstellen);
            printf("         Counter: %d\n",Counter);
            printf("     Werteintrag: %.2f\n\n",Wertetabelle[x][y]);
        }
    


  • Es werden aber nicht zwingend alle Werte im Array vollgeschrieben, daher verstehe ich die 20*4.0 nicht...



  • -Hier standen Unwahrheiten-



  • roflo schrieb:

    Mit

    int m[20][2]
    

    deklarierst du ein Array mit der Größe 2, welches wiederum Arrays mit der Größe 20 enthält.

    Nein, m ist ein Array von 20 Arrays à zwei int s.
    m[y] bezeichnet entsprechend das y te Zweierarray, usw...



  • 😮 Habs grad getestet. Mein Leben beruht auf einer Lüge 🙂



  • Caligulaminus schrieb:

    m[y] bezeichnet entsprechend das y te Zweierarray, usw...

    richtig ist
    das (y-1) te Zweierarray
    wenn y sich auf die Größe des Arrays bezieht.



  • 🙄



  • 😮 Habs grad getestet. Mein Leben beruht auf einer Lüge 🙂

    Kenn ich, ist mir gestern auch aufgefallen mit dem logischen && 😢



  • Mir gings nicht um &&.



  • Is mir schon klar....?



  • Naja wie auch immer 😉
    Was war denn jetzt genau dein Problem?



  • Was war denn jetzt genau dein Problem?

    Jetzt nur noch das Schreiben des letztes Wertes in der Wertetabelle, denn

    Es werden aber nicht zwingend alle Werte im Array vollgeschrieben, daher verstehe ich die 20*4.0 nicht...

    x/20*4.0 ergibt halt etwas völlig anderes als ich da hineingeschrieben haben möchte



  • TocToc schrieb:

    x/20*4.0 ergibt halt etwas völlig anderes als ich da hineingeschrieben haben möchte

    Sorry, wenn das nicht deinen Werten entspricht.

    Zunächst: So habe ich das nicht geschrieben.

    Wenn du einen anderen Wertebereich haben möchtest, musst du die Werte anpassen.
    Ich bin von 20 Werten mit 0.2 Breite ausgegangen. (20 * 0. 2 ist 4.0)
    Wenn du nur 10 Werte haben möchtest, dann ändere die Schleife auf <= 10
    (Das ändert dann aber nichts an dem 20*4.0)



  • Okay, verstanden, aber mir ist gerade eine andere Idee gekommen:
    Ich runde den Wert für die Streifenbreite schon der for-Schleife auf vier Nachkommastellen ab (das war ja nur nen Auzug, die eigentliche Rechnung war ja anders 😉 ).

    Wie genau muss ich das nochmal machen...? lround() oder *1000 0.5...so genau weiß ich das nicht mehr...hat jmd nen Link für mich? Das Thema gabs doch schon mal hier oder? 😕


Log in to reply