Hallo Besucher, der Thread wurde 4,7k mal aufgerufen und enthält 24 Antworten

letzter Beitrag von sauhund am

C-Code kürzen / optimieren

  • Worin besteht dann konkret der Unterschied, ob ich i direkt als float definiere oder eben an der Stelle explizit caste?


    Der Unterschied besteht darin, dass im Fall dass Du i als int definierst, Berechnungen, die direkt i betreffen, eben als ganzzahlige Berechnungen durchgeführt werden und erst anschließend eine Umwandlung nach float erfolgt. Im anderen Fall würdest Du die ganze Zeit mit float rechnen. Das kann sowohl Auswirkungen auf die Genauigkeit haben, als auch auf die Geschwindigkeit. Z.B. wird die Multiplikation (i * i) mit i als int ganzzahlig durchgeführt und erst anschließend nach float gewandelt. Was nun schneller ist, hängt von verschiedenen Faktoren ab, z.B. auf was für einer Maschine der Code läuft (FPU vorhanden oder nicht, etc.).

  • und ohne die jetzt weiter erklären zu wollen sollte man einfach im hinterkopf behalten das in C im zweifelsfall _alles_ implizit nach int gecastet wird. das ergebnis irgendeines ausdrucks in dem ein int vorkommt wird auch wieder zu einem int, auch wenn ein float drin ist.


    Ich habe da mit verschiedenen Compilern schon ganz andere Sachen erlebt. Und Zwangs-Int-Casting machen auch nicht alle.
    Vor allem im Embedded-Bereich mit den creativen Compilern von Microchip, Fujitsu oder Mitsubishi
    ist man da vor lustigen Überraschungen nicht gefeit, deshalt immer ausprobieren oder explizit casten.

  • Das löst man natürlich rekusiv!


    Wenn man was mit einer gleichwertigen Schleife machen kann, macht man es nie rekursiv. Das Anlegen des Stack-Frames kostet Zeit und Speicher. Neuere Compiler optimieren solche Rekursionen wo möglich auch zu einer Schleife.


    Was für ein Kompiler? Evtl musst du das explizit casten, wenn das implizite nicht korrekt greift. Siehe:


    das weiss er ja nicht


    Das weiß er ganz genau, was er da tun muss. Dafür gibt's Regeln im ISO-Standard (schon aus ANSI-Zeiten).


    summe += 1 / ( i * i ) ;


    Der Compiler beginnt so, wie man es als Mensch auch machen würde: i * i => beides int, also int lassen.


    Wenn die Typen unterschiedlich groß sind, wird zum größeren konvertiert, bei Ganzzahltypen immer mindestens auf int (bzw. unsigned). Wenn int und float/double gemischt sind, wird auf float/double konvertiert.


    Dann 1 / bla: Auch beides int, also Ergebnis int.


    Anders, wenn Du i als float deklarierst: i * i = float * float => float
    Dann 1 / bla = int / float, konvertiert zu float / float = float


    Besser als i als float zu deklarieren ist es wirklich, wenigstens eine der Variablen auf der rechten Seite zu casten bzw. als float zu verwenden, z.b.:
    1.0F / (i * i)
    oder
    1 / (float)(i * i)
    oder sogar
    1 / (i * (float)i)
    und natürlich
    1.0F / (float)i * (float)i
    sollten gehen


    Mit besser meine ich: Sonst im Programm wird i ja tatsächlich nicht als float benutzt.
    Varianten 1 oder 2 sind vermutlich die schnellsten (abh. von CPU u.a.), weil dort die wenigsten Rechnungen in float gemacht werden müssen.


    Alles ohne 100% Gewähr, ist spät. Lieber mal ausprobieren.


    die Variable "summe" muss definitiv als float definiert werden.
    Warum aber i auch?


    Wenn die rechte Seite alles int ist wird erst bei der Addition umgewandelt:
    float += int => float = float + int
    Wie oben gezeigt bewirkt das float i, dass die Umwandlung laut Regeln schon früher gemacht werden muss.


    Ist im C-Standard und davon abgeleiteter Literatur alles sehr schön erklärt.

  • Zitat

    Vor allem im Embedded-Bereich mit den creativen Compilern von Microchip, Fujitsu oder Mitsubishi
    ist man da vor lustigen Überraschungen nicht gefeit, deshalt immer ausprobieren oder explizit casten.


    Das sind dann aber schon ganz üble Bugs. Ich weiß, dass man sich im Embedded-Bereich manchmal mit komischen Tools rumschlagen muss, aber so'n Mist sollte man dem Hersteller um die Ohren hauen. Die Umwandlungsregeln sind seit K&R unverändert. (Oder hat der Anwender nicht genau hingesehen? :O )

  • Zitat

    Ich weiß, dass man sich im Embedded-Bereich manchmal mit komischen Tools rumschlagen muss, aber so'n Mist sollte man dem Hersteller um die Ohren hauen.


    leider sind die hersteller da oft sehr lernresistent =P bzw man hat compiler die seit zig jahren aus gutem grund nicht mehr supported sind :)