Anzeige

 Summenformel


Status
Dieses Thema wurde gelöst! Zur Lösung gehen…
#1
Hallo,

ich möchte die Summenformel von" (-1)^i * x^(2i+1)" in C programmieren. Hört sich nicht so schwer an, jedoch tut mein Programm nicht das was ich erwarte.
Hier ist mein Code:

C++:
#include <stdio.h>
#include <math.h>

int main (){

int j=0;
int wert = 0;
double x;

int n;



scanf("%d", &n);
scanf("%f", &x);

for(j = 0; j <=n ; j++){

wert = wert + pow(-1, j) * pow(x, 2*j+1);           

}

printf(" %d", wert);

return 0;


}        

[/ Code


Egal was ich eingebe es kommt immer null heraus und ich sehe gerade leider nicht warum.
Dankeschön im voraus.
 
Zuletzt bearbeitet von einem Moderator:

cwriter

Erfahrenes Mitglied
#2
Egal was ich eingebe es kommt immer null heraus und ich sehe gerade leider nicht warum.
Dankeschön im voraus.
Das Programm sieht auf den ersten Blick korrekt aus (mit der Ausnahme, dass die Typen für pow und "wert" nicht so ganz stimmen, aber bei x > 1 sollte dennoch nicht 0 herauskommen).
pow(-1, j) geht schöner/schneller: (1 + (-2) * (j % 2))

Was gibst du denn ein?
Kannst du mal nach den scanfs ein
C:
printf("n: %d, x: %f\n", n, x);
einbauen und die Werte überprüfen?

Deine "wert"-Variable sollte wohl auch double sein, und das printf sollte entsprechend auch angepasst werden.

Gruss
cwriter

/EDIT: Ohne die exakte Ursache zu kennen:
Floating point ist ungenau. Da dein wert von Typ "int" ist, muss ein Floatingpoint-Wert (das Produkt der pows) nach int konvertiert werden - und das wird immer abgerundet (round to zero, also bei negativen Zahlen aufgerundet). D.h. es kann sein, dass dein pow(-1, j) nicht 1 bzw -1 zurückgibt, sondern +/-0.999999999999999x, und das wird nach 0 gerundet. Wenn der wert selbst ein double ist, dann wird nicht gerundet, und das Resultat hat eine leichte Abweichung. Aber eigentlich dachte ich, dass pow bei +/- 1 als Basis genau ist - dem ist wohl nicht so.
 
Zuletzt bearbeitet:
#4
printf("n: %d, x: %f\n", n, x);

durch Einfügen dieser Zeile in mein Code ist mir aufgefallen, dass mein Programm alle Eingaben für x in 0 umwandelt. Warum weiß ich nicht.
Variable Wert habe ich den Datentypen auch in double geändert. Als Ergebnis kriege ich nun ebefalls null nur in dezimal Form.
 

cwriter

Erfahrenes Mitglied
#5
durch Einfügen dieser Zeile in mein Code ist mir aufgefallen, dass mein Programm alle Eingaben für x in 0 umwandelt. Warum weiß ich nicht.
Variable Wert habe ich den Datentypen auch in double geändert. Als Ergebnis kriege ich nun ebefalls null nur in dezimal Form.
Oha. Kann es sein, dass du die deutsche Notation nutzt? Also z.B. "1,23" statt "1.23"? Und falls du schon "1.23" eingibst, geht es mit "1,23"?
(C-Locales)

Was hast du denn tatsächlich eingeben? Kannst du die Konsolenausgabe hier reinkopieren?

Gruss
cwriter
 

cwriter

Erfahrenes Mitglied
#6
Man verzeihe mir den Doppelpost.

Das Problem ist wie immer viel einfacher als gedacht, und gleichzeitig viel schwieriger:
scanf("%f") liest einen float-wert (4 Bytes). Ein double ist 8 Bytes. Also wurden denormalisierte Floating Points gelesen (die winzigen mit e-315).
Die Lösung:
C:
// Statt
scanf("%f", &x);
// So:
scanf("%lf", %x);
Das "l" steht für "long" = 8 Bytes = sizeof(double) :)

Sorry, ich hätte es früher sehen müssen :(

Gruss
cwriter
 
Gefällt mir: ev95
#7
n-Eingabe:
2
x-Eingabe:
3
Ausgaben --> n: 2, x: 0.000000 //(?!)
Wert: 0.000000


Das ist die Konsolen Ausgabe, ich habe das noch mit zusätzlichen printf's übersichtlicher gemacht.
Ich habe das auch mit unterschiedlichen Notationen ausprobiert und hier halt noch mit einer natürlichen Zahl.
Es kommt immer null heraus bzw. bei der Ausgabe von x


C++:
#include <stdio.h>
#include <math.h>

int main (){

int j=0;
double wert = 0;
double x = 0;

int n;


printf("n-Eingabe:\n");
scanf("%d", &n);
printf("x-Eingabe:\n");
scanf("%f", &x);

printf("Ausgaben --> n: %d, x: %f\n", n, x);

for(j = 0; j <=n ; j++){

  wert =wert + pow(-1,j) * pow(x,2*j+1);          

}

printf("Wert: %f\n", wert);

return 0;


}
[/ Code]


PS: warum wird mein Code nicht in einem Fenster gezeigt wie bei euch? :D
 
Zuletzt bearbeitet von einem Moderator:
#9
Man verzeihe mir den Doppelpost.

Das Problem ist wie immer viel einfacher als gedacht, und gleichzeitig viel schwieriger:
scanf("%f") liest einen float-wert (4 Bytes). Ein double ist 8 Bytes. Also wurden denormalisierte Floating Points gelesen (die winzigen mit e-315).
Die Lösung:
C:
// Statt
scanf("%f", &x);
// So:
scanf("%lf", %x);
Das "l" steht für "long" = 8 Bytes = sizeof(double) :)

Sorry, ich hätte es früher sehen müssen :(

Gruss
cwriter

Daran lag es. Es funktioniert jetzt. Danke :D
 

Technipion

Erfahrenes Mitglied
#13
Ich möchte auch gerne - nur der Vollständigkeit halber - aufzeigen, dass man im Prinzip auch direkt eine Endformel angeben kann:
C:
double summe(double x, unsigned int n)
{
    if (x > 0.9999999 && x < 1.0000001) {
        // x ist quasi 1
        return n % 2 == 0 ? 1.0 : 0.0;
    }
    if (x < -0.9999999 && x > -1.0000001) {
        // x ist quasi -1
        return n % 2 == 0 ? -1.0 : 0.0;
    }
    if (x > -0.0000001 && x < 0.0000001) {
        // x ist quasi 0
        return 0.0;
    }
    
    unsigned int N = n / 2;
    
    double ergebnis = (x - pow(x, 3)) * (pow(x, 4*N + 4) - 1) / (pow(x, 4) - 1);
    
    if (n % 2 == 0) {
        // Korrekturterm
        ergebnis += pow(x, 2*(n+1) + 1);
    }
    
    return ergebnis;
}
Aber ich verstehe schon, dass das ja gar nicht der eigentliche Zweck eurer Übung war ;)

Gruß Technipion
 
Status
Dieses Thema wurde gelöst! Zur Lösung gehen…
Anzeige
Anzeige