Schleifen Aufgabe für die Uni! Brauche dringend Hilfe.



  • #include <stdio.h>
    #include <math.h>
    int main(void)
    {
    double x;
     double n = 1.0;
      int m;
      double k;
      double s;
      double ki;
      double kj;
    
      m = 595683 % 100  ;
    
      if (m > 10){
    
      scanf("%lf",&x);
    
      for (k=0; k < m; k=k+1){
        printf("\n%lf",k);}
        for (ki=0;ki < m;ki=ki+2){
          printf("\n%lf",ki);}
          for (kj=1;kj < m;kj=kj+2){
            printf("\n%lf",kj);}
    
            }
      else 
        { // das hier vergessen? 
        for (k=0; k < 10; ++k){  //k=k+1 = ++k
        printf("\nwert für k: %lf",k);
        }
    
    return 0;
    }
    

    Sorry, hab die C++ Tags vergessen.



  • In dem Thread Quadratwurzelfunktion mit Hilfe einer Reihenentwicklung berechnen (4 Tage alt, letzter Post ist von gestern) ist ein Link auf eine Lösung. Die sollte dir weiter helfen.



  • Lege deinem Lehrer mal nahe, dass der double-printf Formatspezifizierer "%f" ist und nicht "%lf", wie er wahrscheinlich schon jahrelang, euch falsch lehrt.



  • Ich glaube nicht das dies allgemein falsch ist. Hängt sicher auch von der Architektur ab.

    %f für float (32 bit floting point format)
    %lf für double (64 Bit floating point format)

    http://www.cs.cmu.edu/afs/cs.cmu.edu/academic/class/15211/fall.97/www/cxxbasics_one.html

    Was ist eigentlich mit dem 80 bittigen format?



  • Von irgendwelchen Architekturen hängt dies nicht ab, sondern ist in ANSI C so spezifiziert und auch in K&RII so dokumentiert, wenn der Lehrer schon K&R Zeiten bemüht ("long float" für double), dann bitte korrekt und konsequent.



  • lupo1977 schrieb:

    Ich glaube nicht das dies allgemein falsch ist. Hängt sicher auch von der Architektur ab.

    %f für float (32 bit floting point format)
    %lf für double (64 Bit floating point format)

    edit: Hier stand Müll, s.u. Das einzige, was noch stimmt:

    Für float gibt es keinen eigenen Formatspezifizierer, weil floats hier (wegen der Ellipse) bei der Übergabe automatisch in double konvertiert werden.



  • Diese Interpretation ist auch falsch weil unzulässig verkürzend.
    Du ignorierst das explizite UB hierfür im Standard. Es macht also nicht Nichts sondern ist undefiniertes Verhalten.
    `... an optional l specifying that a following n

    conversion specifier applies to a pointer to a long int argument;

    ... If an h , l , or L appears with any other conversion specifier, the behavior is undefined.`
    Kapitel 4.9.6.1 ANSI C



  • Danke, das wusste ich nicht.



  • Danke gut zu wissen.
    Ich setze bei printf auch immer nur %f ein (habe das gerade noch mal überprüft). Auf %lf wäre ich so ohne weiteres auch nicht gekommen. Dennoch erscheint es mir nicht unlogisch das so zu machen. Das ist natürlich meine persönliche Meinung und was im Standard steht gilt nun mal.

    Ist aber trotzdem interessant das es bei scanf dann doch unterschieden wird. Was sagt denn dort der Standard dazu?


  • Mod

    lupo1977 schrieb:

    Ist aber trotzdem interessant das es bei scanf dann doch unterschieden wird. Was sagt denn dort der Standard dazu?

    Der sagt, dass das unterschieden werden muss. Wenn dich mal mit Ellipsen, impliziten Umwandlungen und Call by reference beschäftigst, dann verstehst du auch, warum das nur so und nicht anders sein kann. printf und scanf sind auch nur ganz normale Funktionen, die du so wie sie sind nachprogrammieren könntest, keine magischen Vorgaben aus dem Sprachstandard. Daher müssen sie sich auch an die in C geltenden Regeln (die sind durch den Sprachstandard magisch vorgegeben) halten.



  • Wenn dich mal mit Ellipsen, impliziten Umwandlungen und Call by reference beschäftigst, dann verstehst du auch, warum das nur so und nicht anders sein kann.

    Hier mal ein Beispiel:

    int _tmain(int argc, _TCHAR* argv[])
    {
    012A1380 55                   push        ebp  
    012A1381 8B EC                mov         ebp,esp  
    012A1383 81 EC DC 00 00 00    sub         esp,0DCh  
    012A1389 53                   push        ebx  
    012A138A 56                   push        esi  
    012A138B 57                   push        edi  
    012A138C 8D BD 24 FF FF FF    lea         edi,[ebp-0DCh]  
    012A1392 B9 37 00 00 00       mov         ecx,37h  
    012A1397 B8 CC CC CC CC       mov         eax,0CCCCCCCCh  
    012A139C F3 AB                rep stos    dword ptr es:[edi]  
    	float f = 1.234f;
    012A139E D9 05 54 57 2A 01    fld         dword ptr [__real@3f9df3b6 (12A5754h)]  
    012A13A4 D9 5D F8             fstp        dword ptr [f]  
    	double d = 1.234;
    012A13A7 DD 05 48 57 2A 01    fld         qword ptr [__real@3ff3be76c8b43958 (12A5748h)]  
    012A13AD DD 5D E8             fstp        qword ptr [d]  
    
    	printf("%f\n%f\n", f, d);
    012A13B0 8B F4                mov         esi,esp  
    012A13B2 83 EC 08             sub         esp,8  
    012A13B5 DD 45 E8             fld         qword ptr [d]  
    012A13B8 DD 1C 24             fstp        qword ptr [esp]  
    012A13BB D9 45 F8             fld         dword ptr [f]  
    012A13BE 83 EC 08             sub         esp,8  
    012A13C1 DD 1C 24             fstp        qword ptr [esp]
    012A13C4 68 3C 57 2A 01       push        offset string "%f\n%f\n" (12A573Ch)  
    012A13C9 FF 15 B0 82 2A 01    call        dword ptr [__imp__printf (12A82B0h)]  
    012A13CF 83 C4 14             add         esp,14h  
    012A13D2 3B F4                cmp         esi,esp  
    012A13D4 E8 5D FD FF FF       call        @ILT+305(__RTC_CheckEsp) (12A1136h)  
    
    	return 0;
    012A13D9 33 C0                xor         eax,eax  
    }
    012A13DB 5F                   pop         edi  
    012A13DC 5E                   pop         esi  
    012A13DD 5B                   pop         ebx  
    012A13DE 81 C4 DC 00 00 00    add         esp,0DCh  
    012A13E4 3B EC                cmp         ebp,esp  
    012A13E6 E8 4B FD FF FF       call        @ILT+305(__RTC_CheckEsp) (12A1136h)  
    012A13EB 8B E5                mov         esp,ebp  
    012A13ED 5D                   pop         ebp  
    012A13EE C3                   ret
    

    Offensichtlich werden floats erstmal impliziet auf doubles erweitert? Das ist sicher auch irgendwo so vereinbart.

    Man beachte in diesem Zusammenhang

    012A13B2 83 EC 08             sub         esp,8  
    012A13B5 DD 45 E8             fld         qword ptr [d]  
    012A13B8 DD 1C 24             fstp        qword ptr [esp]  
    012A13BB D9 45 F8             fld         dword ptr [f]  
    012A13BE 83 EC 08             sub         esp,8  
    012A13C1 DD 1C 24             fstp        qword ptr [esp]
    

    Rein technisch wäre es aber auch durchaus denkbar direkt mit floats zu arbeiten.



  • lupo1977 schrieb:

    Offensichtlich werden floats erstmal impliziet auf doubles erweitert? Das ist sicher auch irgendwo so vereinbart.

    Ich meine, das wär schon mal in dem Thread erwähnt worden. Kann mich auch täuschen 🤡



  • Ja stimmt schon. Mir ging es aber eher um das hier:

    Rein technisch wäre es aber auch durchaus denkbar direkt mit floats zu arbeiten.

    sub         esp,8  
    fld         qword ptr [d]  
    fstp        qword ptr [esp]  
    fld         dword ptr [f]  
    sub         esp,4  
    fstp        dword ptr [esp]
    

    Und schwups liegt das eine float auf dem Stack. In der Konsequenz crasht dann printf falls ich nicht dort zwischen %f und %lf unterscheide.


  • Mod

    lupo1977 schrieb:

    Und schwups liegt das eine float auf dem Stack. In der Konsequenz crasht dann printf falls ich nicht dort zwischen %f und %lf unterscheide.

    Nur wenn du dein printf doof programmierst. Was meinst du, wieso das Normale printf dies nicht tut, dies sogar ausdrücklich verbietet?



  • Mit der selben Argumentation könnte man dann auch alle ganzzahligen Typen auf 64 Bit erweitern, um sie dann printf mit %i bzw. %u zu übergeben.

    [Edit]
    Scheint auch so zu sein. Aber es wird 32 Bit (auf meiner 32 Bit Maschine) bevorzugt.
    [/Edit]

    Gibt es eigentlich eine Möglichkeit long double (ich meine die volle Präzision der FPU von 80 Bit) zu nutzen?



  • lupo1977 schrieb:

    Mit der selben Argumentation könnte man dann auch alle ganzzahligen Typen auf 64 Bit erweitern, um sie dann printf mit %i bzw. %u zu übergeben.

    So ähnlich passiert das auch. Alle short- und char-Typen werden für die Übergabe auf int erweitert, deshalb kannst du short und char ja auch mit %d ausgeben. Es gibt zwar auch %hd, aber da wird dann der int-Wert für die Ausgabe wieder zurück in short gewandelt.

    Gibt es eigentlich eine Möglichkeit long double (ich meine die volle Präzision der FPU von 80 Bit) zu nutzen?

    %Ld

    Das ist insgesamt ein Haufen historischer Ballast, aber so ist es nunmal.


Anmelden zum Antworten