- 12V Akku mit 280 Ah bauen         
Ergebnis 1 bis 8 von 8

Thema: Punktrechnung vor Strichrechnung ???

  1. #1
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    05.11.2007
    Beiträge
    1.076

    Punktrechnung vor Strichrechnung ???

    Anzeige

    Praxistest und DIY Projekte
    Hallo zusammen,
    ich bin mal wieder auf ein erstaunliches, bzw. ärgerliches Phänomen bei "C" gestoßen.

    1 << 8 + 1 ergibt 512 ????????

    in Pascal, Modula ergbit es 257

    Mal zur Information:
    Eine Verschiebung nach links entspricht einer Multiplikation mit n hoch x.
    In der Schule wurde mir beigebracht, daß Punktrechnung vor Strichrechnung geht.
    Wie kommt es, daß "C" anderer Meinung ist.
    Hier wird erst die Addition durchgeführt dann die Verschiebung.

    Keiner Sorge, ich hab mir das schon durchgelesen.
    Präzendenz.... in "C" hat eine "eigene Tabelle"
    Ich bin eigentlich nur enttäuscht.
    Siro

  2. #2
    Erfahrener Benutzer Robotik Einstein Avatar von Felix G
    Registriert seit
    29.06.2004
    Ort
    49°32'N 8°40'E
    Alter
    41
    Beiträge
    1.780
    Naja, ein Linksshift ist eben per Definition keine Multiplikation (obwohl er gerne dafür eingesetzt wird)

    verwendet man den "normalen" *-Operator, stimmt auch die Rechnung wieder


    edit:
    auch interessant ist, was der C-Standard zu dem Thema zu sagen hat:
    The result of E1 << E2 is E1 left-shifted E2 bit positions; vacated bits are filled with zeros. If E1 has an unsigned type, the value of the result is E1 × 2^E2, reduced modulo one more than the maximum value representable in the result type. If E1 has a signed type and nonnegative value, and E1 × 2^E2 is representable in the result type, then that is the resulting value; otherwise, the behavior is undefined.
    Man muss also bei diesem Operator schon aufpassen in welchen Fällen man ihn einsetzt, denn nicht immer ist das Ergebnis definiert (beim Rechtsshift als Division ist es noch schlimmer)
    Geändert von Felix G (15.12.2011 um 22:33 Uhr)
    So viele Treppen und so wenig Zeit!

  3. #3
    Erfahrener Benutzer Robotik Einstein Avatar von SprinterSB
    Registriert seit
    09.06.2005
    Ort
    An der Saar
    Beiträge
    2.802
    > Hallo zusammen, ich bin mal wieder auf ein erstaunliches, bzw.
    > ärgerliches Phänomen bei "Spache" gestoßen.

    *Das wird dir mit *jeder* Programmier-, Skript-, Satz-, Markup-Sprache passieren: Tryial by Error ist *immer* ineffektiver als phänomenale Dokumentation lesen!
    Disclaimer: none. Sue me.

  4. #4
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    05.11.2007
    Beiträge
    1.076
    Eigentlich wollte ich dem Compiler etwas Arbeit abnehmen mit dem Shift,
    es gibt ja Controller die nicht multiplizieren können und da bin ich es halt gewohnt zu schieben.
    Hätt ich den normalen Multiplikator verwendet geht es richtig, da stimme ich Felix G völlig zu.
    Ich bin auch erstaunt was der C-Standard dazu sagt.
    "behavior is undefined" "Das Verhalten ist undefiniert"
    Das ist ja wie bei einem FlipFlop: beim Einschalten, "undefinert" man braucht halt einen Vorzugskondensator,
    hier halt die Klammern oder das "*".

    Dokumentation lesen ist sicher nicht verkehrt, da bin ich ganz deiner Meinung.
    Aber wie sagt man so schön: Aus Fehlern lernt man. Und ich glaube auch, daß man durch Analysieren der Fehler oder "Programmierfallen"
    wesentlich mehr lernt als nur vom Lesen.
    Man muss einfach mal loslegen und viel Zeit investieren und auch viel Programmieren und auch "probieren"
    Nach einigen Jahren kommt man dann meist recht gut zurecht.
    Wenn ich dann Bücher sehe wie : Java in 14 Tagen lernen, kann ich nur lachen.
    Programmieren ist ein Prozess in dem man ständig dazulernt und dieser endet nie, auch nicht nach 30 Jahren.
    Und jede Programmiersprache hat seine Eigenheiten, die man dann irgendwann auch kennt.
    Man (ich) ärgert sich dann nur, wenn man bestimmte Dinge in einer anderen Programmiersprache anders gelernt hat als es in der Sprache Y funktioniert
    Macht zieht dann automatisch seine Vergleiche und diese fallen im Moment bei C eher negativ aus.

    Zitat von Sprint SB:
    Computer sind Maschinen, mit denen man Probleme lösen kann, die es ohne sie nicht gäbe.

    ich würd es im Moment so beschreiben, bitte nicht negativ auffassen:
    Mit C kann man Probleme lösen, die man in X garnicht hatte

    Einen schönes Wochenende Euch allen.
    Siro

  5. #5
    Erfahrener Benutzer Begeisterter Techniker
    Registriert seit
    19.05.2005
    Ort
    Berlin
    Beiträge
    316
    Programmieren und Java sind ja auch zwei völlig verschiedene Sachen.
    Java ist "nur" eine Sprache, die kann man locker in 14 Tagen lernen. Kommt man von C#
    braucht's nur einen Tag.

    Programmiererisches Können ist unabhängig von der Sprache. Sich in den Wust der
    Laufzeitbibliotheken einzuarbeiten kann dagegen schon ein wenig Zeit in Anspruch nehmen, vorausgesetzt, man will sofort alles wissen.
    Sonst guckt man einfach in die Dokumentation, dann braucht man nicht einige Jahre um leidlich zurecht zu kommen.

  6. #6
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    02.06.2011
    Beiträge
    158
    Also ich hab mir einfach angewoehnt, alles zu klammern sobald auch nur der geringste Zweifel besteht.
    Und ich hab fast alles durch, von APL bis Z80-Assembler

    Mit Punktrechnung vor Strichrechnung kommst nicht weit, APL ist gleich das erste Beispiel (Auswertung strikt von rechts(!) nach links), Forth ein weiteres ...

  7. #7
    Moderator Robotik Visionär Avatar von radbruch
    Registriert seit
    27.12.2006
    Ort
    Stuttgart
    Alter
    61
    Beiträge
    5.799
    Blog-Einträge
    8
    Hallo

    Addition vor Shift:
    http://de.wikibooks.org/wiki/C-Progr...Priorit%C3%A4t

    Das Stichwort lautet "Bindung der Operatoren"

    "...alles zu klammern sobald auch nur der geringste Zweifel besteht." praktiziere ich auch.

    Gruß

    mic
    Bild hier  
    Atmel’s products are not intended, authorized, or warranted for use
    as components in applications intended to support or sustain life!

  8. #8
    Erfahrener Benutzer Robotik Einstein Avatar von Felix G
    Registriert seit
    29.06.2004
    Ort
    49°32'N 8°40'E
    Alter
    41
    Beiträge
    1.780
    Klammern ist immer gut, dadurch werden solche Ausdrücke auch besser lesbar
    (wenn man trotzdem das Gefühl hat ein Ausdruck wäre mit Klammern schlechter lesbar, dann ist der Ausdruck zu lang und sollte ohnehin in mehrere leichter verdauliche Häppchen zerlegt werden)


    Vielleicht noch eine Kleinigkeit zur Verwendung von Shifts als Ersatz für Multiplikation oder Division:
    Normalerweise tut man das aus Performancegründen, aber nicht immer ist diese Variante auch tatsächlich schneller. Ein ATmega z.B. hat üblicherweise einen eingebauten Multiplizierer, der für eine 8x8 Bit Multiplikation genau 2 Takte benötigt. Ein Linksshift hingegen benötigt nur einen Takt, also müssten Multiplikationen damit ja doppelt so schnell laufen, korrekt?

    Falsch!
    Denn was viele übersehen ist, daß ein ATmega keinen Barrel-Shifter hat, d.h. er kann mit einem Shift-Befehl auch nur um ein Bit shiften. Es bleibt also nur ein einziger Fall übrig bei dem der Shift tatsächlich schneller ist, und das ist die Multiplikation mit 2.

    Programmiert man in Assembler fällt das sofort auf, da die Shift Befehle jeweils nur einen Operanden haben (nämlich das zu shiftende Register). In C hingegen merkt man das überhaupt nicht (wer käme schon auf die Idee, daß "<< 7" mehr Befehle braucht als "<< 2").

    Dazu kommen natürlich noch die schon erwähnten Sonderfälle die man beachten muss, wenn die Ergebnisse auch korrekt sein sollen.


    Das nur mal als kleiner Hinweis am Rande, daß vermeintliche Optimierungen manchmal genau das Gegenteil von dem bewirken, was man eigentlich wollte.
    So viele Treppen und so wenig Zeit!

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •  

12V Akku bauen