Was genau macht diese Codezeile: unsigned int x; int y; x=((y*32768) >> 16); kann es sein, dass hier eine Konversion einer negativen Zahl in eine positive Zahl stattfindet, sofern y negativ ist? mfg miki
1 | |
2 | int y; |
3 | x=((y*32768) >> 16); |
Halte ich für Unsinn. (y*32768) multipliziert y mit 32768. Aber: y kann nur Zahlenwerte zwischen -32768..+32767 annehmen.
1 | (...)>>16 |
teilt das was in der Klammer steht durch 65536 (2hoch16) Ich würde sagen, es kommt (unabhängig von y) immer x=0 raus.
> kann es sein, dass hier eine Konversion einer negativen Zahl in eine > positive Zahl stattfindet, sofern y negativ ist? Kann immer passieren wenn man einer unsigned-Variablen einen signed Wert zuweist (Stichw.: Zweierkomplement). hth. Jörg ps.: die Zeile heißt allerdings effektiv :
1 | unsigned x; |
2 | int y; |
3 | x = y >> 1; |
@lippy: wenn du 16Bit-ints annimmst ist 32768 aber schon ein long und y*32768 wird nach long gewandelt
Jörg X. wrote: > ps.: die Zeile heißt allerdings effektiv : >
1 | > unsigned x; |
2 | > int y; |
3 | > x = y >> 1; |
4 | >
|
Nein. Das tut sie nur dann, wenn es zu keinem Überlauf kommt und das MSB nicht gesetzt wird durch den Shift: da y signed ist, zeiht das Reschtsschieben von y das MSB nach. Unsinn ist sowas nicht unbedingt, könnte zB aus nem Code-Generator rauskommen oder nach Makro-Expansion entstanden sein. Zudem ist nicht über sizeof(int) gesagt.
Jörg X. wrote: > @lippy: > wenn du 16Bit-ints annimmst ist 32768 aber schon ein long Nein, es ist unsigned int. GCC spuckt dafür auch eine Warnung aus (irgendwas mit "constant is so long that it is unsigned" oder so).
>> wenn du 16Bit-ints annimmst ist 32768 aber schon ein long > > Nein, es ist unsigned int. Sicher? Ich dachte, Integer-Konstanten ohne "u" am Ende seien immer signed. Ich bin jetzt zu faul, im Standard nachzuschlagen, aber der AVR-GCC behauptet: sizeof 32768 ist 4 sizeof 32768u ist 2 sizeof 65536u ist 4 Also scheinen Werte ab 32768 tatsächlich long zu sein, entsprechend sind Werte ab 65536u unsigned long.
yalu wrote: >>> wenn du 16Bit-ints annimmst ist 32768 aber schon ein long >> >> Nein, es ist unsigned int. > > Sicher? Ich dachte, Integer-Konstanten ohne "u" am Ende seien immer > signed. Ah, hast Recht, oder: jein. Dezimale Konstanten sind immer signed. Nur bei oktalen und hexadezimalen Konstanten wird ein unsigned-Typ benutzt, wenn der entsprechende signed-Typ nicht mehr zur Darstellung ausreicht.
Vorsicht! Jede Konstante ohne suffix ist immer "signed int", egal ob Decimal, Hex oder Octal, s. ISO Beschreibung. Und weiter gilt noch die "integer promotion" Regel: .... If an int can represent all values of the original type, the value is converted to an int; otherwise, it is converted to an unsigned int. These are called the integer promotions.48) All other types are unchanged by the integer promotions. ..... ‘‘integer promotions’’ require that the abstract machine promote the value of each variable to int size and then add the two ints and truncate the sum. Provided the addition of two chars can be done without overflow, or with overflow wrapping silently to produce the correct result, the actual execution need only produce the same result, possibly omitting the promotions. Beispiel: char c1, c2, c3; ... c1 = c2 + c3; Ganz nach ISO (wie z.B. die RISC Prozessoren) Compiler macht davon: c1 = (char)( (int)c2 + (int)c3 ); Und ganz unsauber ist signed und unsigned Operands zusammen mischen.
Hans wrote: > Vorsicht! Jede Konstante ohne suffix ist immer "signed int", egal ob > Decimal, Hex oder Octal, s. ISO Beschreibung. Nein, ebendiese Beschreibung besagt, dass eine oktale oder dezimale Konstante "unsigned int" wird, falls sie nicht als "signed int" represäntierbar ist. Nur dezimale Konstanten sind immer vorzeichen- behaftet, sie wandern sofort von "int" nach "long int", wenn's nicht mehr passt. Damit ist 32768 vom Typ "long int", aber 0x8000 ist "unsigned int".
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.