Forum: Compiler & IDEs Programmcode Problem


von John Muth-Blöm (Gast)


Lesenswert?

Kann mir einer erklären was hier gemacht wird mit einem Beispiel?

unsigned char a,b,c;

a |= b >> (8-c);

Und wie kann man das in Codevision schreiben?

danke

von Oma-mit-Dackel (Gast)


Lesenswert?

Hi,

hier ein Beispiel: a=16, b=8, c=6 jetzt dargestellt in Binär

Binär a:0001'0000
      b:0000'1000
      c:0000'0110

Am besten immer mit der inneren Klammer anfangen hier(8-c)........... 8
- Inhalt von c ... 8-6 = 2
in Binär:
=0000'1000-0000'0110 = 0000'0010
                ||||
                8421 <-Wertigkeit der Stelle immer 1,2,4,8,16,32....

danach (b >> (8-c)) hier wird der Inhalt von b um (8-6) also 2 Stellen
nach rechts verschoben >> (nach links wäre <<)
in Binär:
      b:0000'1000 >> 2 Stellen = 0000'0010

b wird in diesem Beispiel zu 2 oder Binär 0000'0010

zum Schluss wird a mit sich selbst und b Bitweise ODER Verknüpft
a |= b ist die Kurzschreibweise für a=a ODER b
in Binär:
      a:0001'0000
      b:0000'0010
---------------------
    a=  0001'0010   der Inhalt von a ist am Ende aller Operationen
                    18

Ich hoffe es hat dir jetzt weitergeholfen ...

von John Muth-Blöm (Gast)


Lesenswert?

Vielen Dank dir dafür war ausführlicher als ich es mir erhoft habe.
Das ist ja Standart C, dann kann ich es Problemlos auch in Codevision
so  schreiben. oder?

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

> Das ist ja Standart C, dann kann ich es Problemlos auch in
> Codevision so schreiben.

Wenn Codevision ein Standard-C-Compiler ist (was ich hoffe), ja.

Ansonsten bist du hier leicht im falschen Forum -- hier sind die
GCC-Freaks versammelt, damit wirst du eher nur zufällig jemanden
treffen, der auch Codevision kennt.

von Oma-mit-Dackel (Gast)


Lesenswert?

Hi,

probier'n geht über studier'n also ran und ausprobieren :-).

Gruss

von Peter D. (peda)


Lesenswert?

a =| b >> (8-c);


Solchen Code sieht man häufig bei Leuten, die sich nicht mit der
CPU-Architektur beschäftigen wollen.

Der AVR hat nämlich keinen n-fach Schiftbefehl, d.h. solche Konstrukte
müssen super umständlich per extra Schleife emuliert werden.

ist c z.B. ein Schleifenzähler:

for( c = 8; c; c-- ){
...
a =| b >> (8-c);
...
}

läßt sich die Geschwindigkeit ganz einfach drastisch erhöhen:

for( c = 8; c; c-- ){
...
a =| b;
b >>= 1;
...
}


Zwischen mathematisch richtig und effizient besteht daher oft ein
riesen Unterschied.

Und so kommt es, daß manche für die gleiche Aufgabe eine 10-fach
schnellere CPU benötigen.


Peter

von Oma-mit-Dackel (Gast)


Lesenswert?

Hi Peter,

für mich ist ein C-Compiler wie ein Auto...ich benutze ihn um schnell
von A nach B zu kommen....ohne jede Schraube persönlich zu kennen. Für
mich als Hobbyanwender reicht das alle mal. Und sollte es doch mal
Zeitkritisch werden wird eine Assemblerroutine geschrieben. Also rege
dich nicht über uns unwürdige auf :-) Ich habe jedenfalls noch keinen
C-Compiler geschrieben und weiss auch nicht wie dieser intern
funktioniert. Das ist für mich auch nicht wichtig, die Hauptsache das
resultierende Programm tut das wofür es konzipiert wurde.

Gruss

von Peter Dannegger (Gast)


Lesenswert?

@Oma-mit-Dackel

das war doch nur ein Hinweis und Du darfst ihn komplett ignorieren.

Nur wundere Dich nicht, daß andere Programme 10-mal schneller sind.

Man muß auch nicht die CPU wie seine Westentasche kennen.

Allgemein gilt eben, daß einfachere Ausdrücke oftmals auch schneller
sind. Man kann also mit dem gesunden Menschenverstand schon viel
optimieren und oft wird dann das Programm auch lesbarer.


Ich weiß, ein Mathematiker mag komplexe und schlecht verstehbare
Ausdrücke. Ein Programmierer schießt sich damit aber nur selbst ins
Knie.

Ein Programmierer darf nie eine mathetische Formel abtippen, sondern er
muß sie nachvollziehen.
Denn in der Praxis gibt es keine unendlich großen und unendlich genauen
Zahlen, d.h. man muß immer den Wertebereich abschätzen können, damit es
nicht zu Fehlern kommt (Überlauf, Divison durch 0 usw.).


Peter

von Oma-mit-Dackel (Gast)


Lesenswert?

Hi Peter,

ich muss jetzt auch über meine Meinung lachen, da ich ein Phänomen
nicht verstehe(wäre vielleicht doch besser zu verstehen was GCC macht).
Beim Versuch eine float Variable in einem IF-Ausdruck zu überprüfen kann
dieser nicht zwischen negativer und positiver Zahl unterscheiden.

             float e=0, ....;
             e=-1;
             if(e>0)..... //geht bei mir in die Hose und wird als TRUE
erkannt

Sollte meine Aura Schuld sein ?
Wahrscheinlich überprüft der Ausdruck nur ob in der Variablen e etwas
drin steht. Bei FALSE in HEX 0x00 in e muss ich erst überprüfen ob er
es dann doch als Falsch anerkennt..... Und zu deiner Antwort: Grins du
hast Recht, wer Formeln nur stupide eingibt wird über die nachfolgenden
Effekte ins staunen kommen. Man sollte seine Programme vor Gebrauch auch
testen.

Gruss

von Steffen (Gast)


Lesenswert?

Hallo

Vergleichsoperatoren wie > < oder == funktionieren nur
mit Integertypen wie char, int, usw, nicht mit float.
Bei anderen Programmiersprachen erscheint da sofort
eine Fehlermeldung, während C einfach irgendwas als Ergebnis ausgibt.

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

> Vergleichsoperatoren wie > < oder == funktionieren nur mit
> Integertypen wie char, int, usw, nicht mit float.

Sorry, aber das ist kompletter Unsinn.

Selbstverständlich funktionieren alle diese Vergleichsoperatoren auch
mit Gleitkommazahlen in C.

Was nicht funktioniert ist lediglich der Vergleich auf exakte
Gleichheit für Zahlen, die binär nicht ,,glatt'' darstellbar sind.
Was garantiert funktioniert ist der Vergleich auf eine echte 0.0,
allerdings dürfte eine solche selten als Rechergebnis auftauchen.
Aber was real machbar ist und auch durch den Standard m.E. abgedeckt
ist sind Dinge wie:
1
...
2
double f = 0.0;
3
...
4
while (...) {
5
   if (...) f = foobar(); /* irgendwas != 0.0 */
6
}
7
8
if (f == 0.0) {
9
   /* foobar() wurde nicht aufgerufen */
10
}

Mit IEEE-Gleitkommazahlen würden auch Vergleiche auf ..., .25, .5,
1.0, 2.0, ... sicher funktionieren, aber darauf würde ich mich nicht
verlassen, da es nicht portabel ist.  Sinnvoller ist es, auf Bereiche
zu vergleichen:
1
if (x < 1.999 && x > 2.01) {
2
  ...
3
}

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Die komischen 0.00.0 da oben sind ein Bug in der Forumsoftware,
das waren ursprünglich 0.0.

von Peter Dannegger (Gast)


Lesenswert?

@Oma-mit-Dackel

probiers mal so:

e=-1.0;
if(e>0.0).....


Ansonsten könnte es sein, daß die floating point Lib gar nicht gelinkt
wird.


Peter

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Erstens entscheidet man selbst, ob man die libm.a mit linkt
(-lm, ist standardmäßig in den Makefiles mit drin), zweitens
ist das eigentlich egal, die wird dafür nicht gebraucht.

Solange kein Beweis vorliegt, glaube ich obige Aussage einfach
mal nicht.

von Oma-mit-Dackel (Gast)


Lesenswert?

Huhu,

und danke für euer Feedback.

@Steffen

JÖrg hat Recht ... unter Borland C++ gibt es da auch keine Probleme.
FLOAT-Variablen machen in einer IF Abfrage keine Probleme.

@Peter ... so hat es leider auch nicht funktioniert. Ich muss wirklich
einen Bereich unter FLOAT-Variablen abfragen siehe Programm Jörg ...
Das ist ja ein Ding !!!!

Danke nochmals ...

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.