Ausgabe von Wert falsch

  • Hallo Leute,

    habe gerade ein Programm fast ganz fertig bekommen.
    Es soll den Mittelwert von x eingegebenen (maximal 20) float Werten ausgeben und die Standardabweichung.

    Der Mittelwert wird richtig ausgegeben, aber bei der Abweichung bekomme ich irgendwie -1.#IND00.
    Als Testdaten habe ich 4 Werte eingegeben, und zwar 4, 5, 6, 5.
    Mittelwert: 5 stimmt
    Abweichung müsste 0.707 sein, aber kommt wie gesagt nicht raus.

    Die Formel für die Abweichung ist ja wie hier
    http://de.wikipedia.org/wiki/Geometrische_Standardabweichung

    Das zweite x mit dem Oberstrich steht ja für den Mittelwert.

    Was mache ich falsch? Alles scheint zu funktionieren bis auf das mit der Berechnung der Abweichung. Habe ich da einen Fehler?

    Hier mal mein Quellcode:


    VIelen Dank fürs Lesen!

  • s=sqrt((1/anzahl)*s);


    ich glaube, dass es an dieser zeile liegt: anzahl ist vom typ integer, also wird auch 1 vom typ integer genommen -> integer dividiert durch integer = integer -> und wenn ich mich richtig erinnere wird immer abgerundet -> also 1/5=0, 10/4=2 -> 0*s=0
    versuch mal anzahl vom typ float bzw schreib

    Code
    s=sqrt(([B]1.00[/B]/anzahl)*s);


    denn dann müsste das ergebnis der division ein float sein.

    *** Ich würde gern die Welt verändern, aber Gott gibt mir den Quelltext nicht ***

  • Danke für deinen Tipp!

    Es hat ausgereicht die 1 in 1.00 im Zähler zu schreiben.

    Und dann war ausschlaggebend, dass ich in der Funktion ganz oben den Mittelwert m nicht zurückgegeben habe, also return m.

    Jetzt läuft es prima!

    Danke nochmal!

  • Jetzt habe ich doch noch ein Problem.

    Und zwar muss ich die Funktionen zur Berechnung des Mittelwertes mittel(anzahl) und der Abweichung abweichung(anzahl) in eine headerdatei speichern.

    Ich habe das schon mal gemacht bei Vektoraufgabe. War aber etwas anders.

    Ich habe also drei Dateien
    main.c
    messwerte.c (die Funktionen)
    messwerte.h (die Funktionsdeklarationen)

    in messwerte.c habe ich


    messwerte.h

    Code
    #ifndef MESSWERTE_H
    #define MESSWERTE_H
    
    
    float mittel(int i);
    float abweichung(int i);
    
    
    #endif

    main.c


    Wenn ich das in Visual Studio eingebe läuft das Programm zwar, aber bekomme beim Mittelwert und bei der Abweichung mit meinen Zahlen -1.#IND00 raus was ja nicht richtig ist.

    habe ich bei den Definitionen in der messwerte.h oder messwerte.c was vergessen?

  • du hast in messwerte.c globale variablen namens i, anzahl, m, messwert usw

    die haben nur innerhalb dieser datei gültigkeit, soweit ich mich erinnern kann wie das in c läuft, jedenfalls tust du in der main nochmal eine anzahl, messwert usw definieren, die anzahl übergibst du als funktionsparameter, da ist es also egal, aber beim messwert nicht

    du liest also in die messwert variable in der main rein und messwerte.c benutzt aber die nicht initialisierte globale messwert variable in der messwerte.c datei

    da steht nur speichermüll drin da du sie ja nicht initialisiert hast

    ein zweiter fehler ist, du übergibst den beiden funktionen in der main "anzahl", in den funktionen heißt der parameter der anzahl bekommt i

    du hast aber in messwerte.c schon eine globale variable mit dem namen i definiert, wenn du also i = 0 schreibst in der for schleife gibt der compiler dem "int i" funktionsparameter den vorzug über der globalen variable i

    also du willst eigentlich den globalen zähler i auf = 0 setzen aber da du eine lokale variable i hast wird die mit dem namen i assoziiert (wenn globale und lokale variablen gleiche namen haben bekommen die lokalen den vorzug), du setzt also im endeffekt deinen parameter (=die anzahl die du übergeben hast) auf 0

    außerdem steht in der for schleife dann i < anzahl

    aber die globale variable anzahl in der messwerte.c datei ist wieder nicht definiert, mit anzahl meinst du semantisch natürlich die anzahl an werten die du hast aber die hast du in den parameter i übergeben

    du hast also erstmal die namen i und anzahl verpfuscht und zweitens bist du mit den globalen variablen durcheinander gekommen

    es gibt zwei sehr wichtige regeln, erstens solltest du nach möglichkeit keine globalen variablen verwenden (wenn du dennoch messwert global machen willst schau dir an wie das keyword extern funktioniert)

    aber du solltest jedenfalls keine globalen variablen machen und das messwert array ebenso wie die anzahl als parameter in die beiden funktionen reintun

    die zweite sehr wichtige regel die du verletzt hast ist, sprechende variablennamen verwenden, was ist m, was ist s, was ist anzahl, wieso heißt das messwert array messwert?

    i ist ok, i, j, k werden meistens einfach für for schleifen als zähler verwendet das kannst du so lassen

    aber
    - messwert ist ein array aus messwerten, nenn es also messwerte
    - anzahl ist die anzahl der messwerte, nenn sie also messwerteLaenge, messwerteAnzahl oä
    - m ist der mittelwert, nenn die variable also mittelwert

    etc etc, jetzt ist das noch egal aber wenn du große programme schreibst dann hast du irgendwann a = b * c + i; for(x=k; y != varMin; x++) { varMin *= a % varMax; }

    oder solche konstrukte und du hast keinen plan mehr was was ist und musst dauernd nachschauen weil du keine sprechenden namen verwendet hast, und wenn es sich nicht gerade um ganz eindeutige abkürzungen wie Min und Max handelt schreib abkürzungen immer aus

    wenn das programm trotzdem nicht zum laufen willst frag nochmal nach dann zeig ich dir wie ichs gemeit hab aber versuchs mal selbst

    [FONT=Arial, Helvetica, sans-serif](\__/) [/FONT]
    [FONT=Arial, Helvetica, sans-serif] (='.'=) [/FONT]This is Bunny. Copy Bunny into your signature to help
    [FONT=Arial, Helvetica, sans-serif](")_(")[/FONT] him on his way to world domination.

  • Hallo,

    danke für die Erklärungen.

    Ich hab eben gesehen was du meinst, hab schon geahnt es liegt an den Variablen.

    Jetzt habe ich um es mir zu erleichtern die Eingabeschleife

    Code
    for (i=0;i<anzahl;i++)
    {
        scanf("%f", &messwert[i]);
    }

    aus main.c rausgenommen und in messwerte.c in die double mittel Funktion eingefügt.

    Dann habe ich in main.c für die Eingabe der Anzahl der Zahlen die Variable x genommen.
    Diese wird dann der mittel Funktion in messwerte.c übergeben. Entsprechend habe ich dann die Funktionen verändert.

    double mittel(int anzahl)
    double abweichungl(int anzahl)

    Somit wird ja x der Variablen anzahl übergeben.
    messwert[i] sind die Zahlen die eingegeben/eingelesen werden.

    Dann habe ich wieder durchlaufen lassen und meine 4 Zahlen eingegeben: 4, 5, 6, 5.

    Aber bekomme leider 0.00000 raus, beim Mittelwert, als auch der Abweichung...

    Hier nochmal die veränderten Dateien
    main.c

    messwerte.c

    messwerte.h

    Code
    #ifndef MESSWERTE_H
    #define MESSWERTE_H
    
    
    double mittel(int anzahl);
    double abweichung(int anzahl);
    
    
     #endif

    Was stimmt noch nicht?

  • Der war echt nicht so einfach zu erkennen: Für double musst du bei scanf nicht %f verwenden, sondern %lf (%f ist für float). Also:

    Code
    scanf("%lf",&messwert[i]);

    Wegen den globalen Variablen: i, anzahl, s und m sollten definitiv keine sein, das führt nur zu Problemen.
    Wenn du in deinem Header

    Code
    extern messwert[20];

    schreibst, kannst du von main.c darauf ganz normal zugreifen, und es gibt nur eine Variante davon.

    [font=verdana,sans-serif]"An über-programmer is likely to be someone who stares quietly into space and then says 'Hmm. I think I've seen something like this before.'" -- John D. Cock[/font]

    opentu.net - freier, unzensierter Informationsaustausch via IRC-Channel!
    Hilfe und Support in Studienangelegenheiten, gemütliches Beisammensein, von und mit Leuten aus dem Informatik-Forum!

  • Danke!

    So einen Fehler hatte ich schon mal bei einem anderen Programm...

    Jetzt geht es aber.

    Wegen den Variablen i, anzahl, s und m. Wo soll ich sie dann definieren?

    und extern mittelwert[20]; kann ich in messwerte.h schreiben und double messwert[20]; in messwerte.c lassen?

    Weil ich bekomme die Meldung:
    'messwert': Neudefinition; unterschiedliche Basistypen

  • Wegen den Variablen i, anzahl, s und m. Wo soll ich sie dann definieren?

    In dem Block, wo sie gebraucht werden. Falls du C99 verwendest, kannst du sogar

    Code
    for(int i=0; i < bla; i++)

    schreiben, ansonsten halt in der Funktion nach dem ersten {.

    Zitat

    und extern mittelwert[20]; kann ich in messwerte.h schreiben und double messwert[20]; in messwerte.c lassen?

    Weil ich bekomme die Meldung:
    'messwert': Neudefinition; unterschiedliche Basistypen

    Hoppla, ich hab double vergessen:

    Code
    extern double messwert[20];

    Default-Typ ist in C int.

    [font=verdana,sans-serif]"An über-programmer is likely to be someone who stares quietly into space and then says 'Hmm. I think I've seen something like this before.'" -- John D. Cock[/font]

    opentu.net - freier, unzensierter Informationsaustausch via IRC-Channel!
    Hilfe und Support in Studienangelegenheiten, gemütliches Beisammensein, von und mit Leuten aus dem Informatik-Forum!

  • Danke für den Tipp. ich hab double messwert[20]; in der messwert.c gelassen und zusätzlich extern double messwert[20]; in die messwert.h reingeschrieben. Jetzt kann ich auch in der main.c drauf zugreifen.

    Normal habe ich die messwert[20]; in der main.c nur wegen der Eingabe der Zahlen gebraucht. Aber die macht ja jetzt die double mittel am anfang.
    So erspare ich mir eine weitere int Variable in der main.c.

    nochmal wegen den Variablen i, s und m. Die brauche ich in beiden Funktionen, also double mittel und double abweichung. Deshalb hab ich sie global. oder meintest es anders?

  • Normal habe ich die messwert[20]; in der main.c nur wegen der Eingabe der Zahlen gebraucht. Aber die macht ja jetzt die double mittel am anfang.

    Naja, das ist aber sehr unsauber programmiert, weil niemand anhand der Funktionsnamen auf den Nebeneffekt, dass er die Zahlen von der Tastatur einliest, schließen würde. Ich würde empfehlen, eine zusätzliche Funktion dafür zu verwenden. Nur weil etwas richtig läuft heißts nicht, dass es sauber ist :)

    Zitat

    So erspare ich mir eine weitere int Variable in der main.c.

    Die kosten nichts, solange es nicht mehr Variablen als Register auf der CPU vorhanden sind sind :)

    Zitat

    nochmal wegen den Variablen i, s und m. Die brauche ich in beiden Funktionen, also double mittel und double abweichung. Deshalb hab ich sie global. oder meintest es anders?

    Nein, du brauchst sie nicht in beiden. Du brauchst Variablen, die gleich heißen, aber du musst keine Werte über diese zwischen den Funktionen (oder zwischen mehreren Aufrufen der Funktionen) transportieren.

    [font=verdana,sans-serif]"An über-programmer is likely to be someone who stares quietly into space and then says 'Hmm. I think I've seen something like this before.'" -- John D. Cock[/font]

    opentu.net - freier, unzensierter Informationsaustausch via IRC-Channel!
    Hilfe und Support in Studienangelegenheiten, gemütliches Beisammensein, von und mit Leuten aus dem Informatik-Forum!

  • Ja das stimmt, ist nicht wirklich sauber, was mich auch stört.

    ich habe deshalb in der messwert.c noch die funktion double einlesen(int anzahl) definiert und läuft jetzt auch so.

    Danke nochmal!


    Kleine Frage zu einem Programm wo ich sagen soll was für eine Bildschirmausgabe es bewirkt.

    Wenn ich es so übernehme bekomm ich einen Fehler, weil g[/d] keine Zuweisung bekommen hat.
    Ich nehme mal an, den Fehler hat der prof ausversehen gemacht.
    Ich habe dann mal einfach für g=0 gesetzt.

    Meine Bildschirmausgabe ist dann
    [b]21 12 23 14 5 0 0
    wobei die letzte Null ich ja so gesetzt habe.

    Jetzt frage ich mich was soll dabei so besonders sein, bei der Ausgabe?
    Sieht das jemand?

  • Naja, vermutlich gehts da um den Gültigkeitsbereich von Variablen. Das c und e in der Funktion sind andere Variablen als die globalen c und e.
    Falls jemand solchen Code aber wirklich ernsthaft in einem Programm verwenden will, gehört er erschlagen :)

    [font=verdana,sans-serif]"An über-programmer is likely to be someone who stares quietly into space and then says 'Hmm. I think I've seen something like this before.'" -- John D. Cock[/font]

    opentu.net - freier, unzensierter Informationsaustausch via IRC-Channel!
    Hilfe und Support in Studienangelegenheiten, gemütliches Beisammensein, von und mit Leuten aus dem Informatik-Forum!

Jetzt mitmachen!

Sie haben noch kein Benutzerkonto auf unserer Seite? Registrieren Sie sich kostenlos und nehmen Sie an unserer Community teil!