Guten Tag,
ich habe eine Frage:
Ich kenne C bestimmt noch nicht genug tief, aber ich habe geglaubt, daß
diese zwei Zeilen äquivalent sind:
1
if(freq_zaehler&(1<<15))phase_index|=(1<<0);
und
1
if(freq_zaehler&0x00008000)phase_index|=(1<<0);
Trotzdem bekomme ich unterschiedliches Assembler-Ergebnis:
1
if(freq_zaehler&(1<<15))phase_index|=(1<<0);
2
ldsr20,0x04C6;0x8004c6<freq_zaehler>
3
ldsr21,0x04C7;0x8004c7<freq_zaehler+0x1>
4
ldsr22,0x04C8;0x8004c8<freq_zaehler+0x2>
5
ldsr23,0x04C9;0x8004c9<freq_zaehler+0x3>
6
eorr20,r20
7
andir21,0x80;128
8
orr20,r21
9
orr20,r22
10
orr20,r23
11
breq.+2
12
orir24,0x01
und
1
if(freq_zaehler&0x00008000)phase_index|=(1<<0);
2
ldsr20,0x04C6;0x8004c6<freq_zaehler>
3
ldsr21,0x04C7;0x8004c7<freq_zaehler+0x1>
4
ldsr22,0x04C8;0x8004c8<freq_zaehler+0x2>
5
ldsr23,0x04C9;0x8004c9<freq_zaehler+0x3>
6
sbrcr21,7
7
orir24,0x01
Woran liegt das?
freq_zaehler ist unsigned long, phase_index ist unsigned int,
Atmel AVR 8-bit GNU Toolchain 3.6.0.1734 (avr-gcc-5.4.0.exe), AVR Studio
4.19
Vielen Dank im voraus für eine Erklärung.
Maxim B. schrieb:> if(freq_zaehler & (1<<15)) phase_index |= (1<<0);
Vorsicht: Du schiebst hier die "1" ins Vorzeichenbit eines int. Das ist
IIRC laut Standard undefiniertes Verhalten, Du wolltest hier eher sowas
wie (1UL<<15) schreiben.
Maxim B. schrieb:> Ich kenne C bestimmt noch nicht genug tief, aber ich habe geglaubt, daß> diese zwei Zeilen äquivalent sind:if(freq_zaehler & (1<<15)) phase_index> |= (1<<0);undif(freq_zaehler & 0x00008000) phase_index |= (1<<0);> Trotzdem bekomme ich unterschiedliches Assembler-Ergebnis
Inhaltlich mögen die beiden Ausdrücke letztlich das gleiche Resultat
bewirken, dennoch sind es ja verschiedene Ausdrücke und haben demnach
einen verschiedenen Assembleroutput.
Dr. Sommer schrieb:> Optimierungen sind eingeschaltet?
Selbstverständlich.
Aber nun kapiere ich: alles, was nicht anders definiert ist, betrachtet
Compieler als int. Das habe ich vergessen.
Vielen Dank!
aber auch so wird nicht besser, komischerweise:
Maxim B. schrieb:> (unsigned long)(1<<15)
Du shifftest noch immer den int und erweiterst das unsichere Ergebnis
auf long.
Jim M. schrieb:> Du wolltest hier eher sowas> wie (1UL<<15) schreiben.
Der Ausdruck 1<<15 ist, wie von Jim bereits angemerkt, undefiniert. Der
GCC liefert dafür naheliegenderweise den signed-int-Wert 0x8000 = -32768
(was aber nicht garantiert ist). -32768 auf (unsigned) long erweitert
hat das Bitmuster 0xffff8000. Die if-Bedingung wird also immer dann
wahr, wenn in freq_zaehler mindestens eins der Bits 15 bis 31 gesetzt
ist. Das ist natürlich nicht das, was du erwartet hast.
Vielen Dank für Ihre ausführliche Erklärungen!
Das ist ein Versuch, DDS mit einer 12 bit 480 Wort-Tabelle zu
realisieren (480 kann man leicher als 512 auf 2,3,4,5,8,10,12,16
dividieren, das macht Berechnungen für Tabelle leichter). Ich wollte
wissen, ob das alles zeitlich mit akzeptabler Frequenz(z.B. 40 kHz)
machbar ist. MK sollte noch ja etwas Zeit haben, um Befehle von außen zu
nehmen.
Deshalb überprüfe ich das mit Simulator, um später keine bösen
Überraschungen zu bekommen. Immerhin gibt es genug anderen
Fehlerquellen.
Variablen für Frequenz werde ich als __uint24 benutzen, die können aber
in Simulator nicht in Watch-Fenster gesehen werden, deshalb zuerst
unsigned long.
Wahrscheinlich sollte ich für die Zukunft die Ausdrücke wie x & (1<<nn)
nur für Register und Ports benutzen. Alles anderes mit direkten
Konstanten.
Weil klugsch... soviel Spass macht:
Yalu X. schrieb:> Der Ausdruck 1<<15 ist, wie von Jim bereits angemerkt, undefiniert.
C++14 erklärt von allen zuvor undefinierten Fällen genau diesen als
definiert (den, bei dem 1 in das Vorzeichenbit geschoben wird).
tictactoe schrieb:> Weil klugsch... soviel Spass macht:>> Yalu X. schrieb:>> Der Ausdruck 1<<15 ist, wie von Jim bereits angemerkt, undefiniert.>> C++14 erklärt von allen zuvor undefinierten Fällen genau diesen als> definiert (den, bei dem 1 in das Vorzeichenbit geschoben wird).
Vielen dank fürs klugsch... (ernsthaft)! Kannst du angeben wo genau es
im Standard definiert wird (bin zu faul zum Suchen ;-) )
mh schrieb:> tictactoe schrieb:>> Weil klugsch... soviel Spass macht:>>>> Yalu X. schrieb:>>> Der Ausdruck 1<<15 ist, wie von Jim bereits angemerkt, undefiniert.>>>> C++14 erklärt von allen zuvor undefinierten Fällen genau diesen als>> definiert (den, bei dem 1 in das Vorzeichenbit geschoben wird).>> Vielen dank fürs klugsch... (ernsthaft)! Kannst du angeben wo genau es> im Standard definiert wird (bin zu faul zum Suchen ;-) )
Hier: http://www.eel.is/c++draft/expr.shift#2.sentence-3 (aka 8.5.7p2)
oder auch hier:
http://en.cppreference.com/w/cpp/language/operator_arithmetic Abschnitt
Bitwise shift operators.