Hallo,
das Bit-Shiften funktioniert nicht. Die oberen 32 Bit sind immer 0.
uint64_t ullValue = 0xFFFFFFFF;
uint8_t ucValue = (uint8_t)((uint64_t)(ullValue >> 40));
Ergebnis: ucValue = 0
Wie kann ich auf die oberen 32 Bit zugreifen ?
Gruß Peter
Peter schrieb:> Hallo,>> das Bit-Shiften funktioniert nicht.
Doch, tut es.
Peter schrieb:> 32> …> ullValue >> 40
Denk da nochmal kurz drüber nach.
> Ergebnis: ucValue = 0
Das ist richtig.
Oliver
Peter schrieb:> Hallo,>> das Bit-Shiften funktioniert nicht. Die oberen 32 Bit sind immer 0.>> uint64_t ullValue = 0xFFFFFFFF;> uint8_t ucValue = (uint8_t)((uint64_t)(ullValue >> 40));>> Ergebnis: ucValue = 0>> Wie kann ich auf die oberen 32 Bit zugreifen ?>> Gruß Peter
Ist ja auch richtig, wenn man den uint64_t nur zur Hälfte befüllt.
Versuchs mal mit 0xFFFFFFFFFFFFFFFF...
Ach, was solls:
Oliver S. schrieb:> Denk da nochmal kurz drüber nach.Tim T. schrieb:> Ist ja auch richtig, wenn man den uint64_t nur zur Hälfte befüllt.
OMG! - Ich stelle fest: 8 x F != 8 Bytes !!!!
Ich mach da schon ne Stunde rum :)
DANKE an Euch.
Gruß Peter
Oliver S. schrieb:> Das wurde erst nach Peters C-Sozialisierung erfunden...
wobei, wenn ich alle Bits gesetzt haben möchte, würde ich wahrscheinlich
statt
Walter T. schrieb:> Ich weiß> gerade nur nicht, warum. Zumindest bei der Erzeugnung eines> 32-Bit-Binaries auf einem 64-Bit-System.
Weil der Compiler "annimmt", dass es sich bei "0" um eine Zahl aus dem
Zielzahlenbereich "uint64_t" handelt?!
Peter D. schrieb:> Man kann auch einfacher schreiben:uint64_t ullValue = -1;> Als Zuweisung sind signed Werte erlaubt. Sie werden dann in den> entsprechenden Binärwert konvertiert.
Da würde ich vermuten, dass ein Warning erzeugt wird (zumindest meckert
"mein" Keil rum: "warning: #68-D: integer conversion resulted in a
change of sign"). Ein Cast sollte reichen.
Ich habe meinen vorheriges Edit gelöscht, weil mein vorheriger Einwand
gegenstandslos geworden war. Deswegen passt das Zitat nicht mehr zu
meinem Beitrag.
Sinngemäß stand da: "Nanu, uint64_t a = ~0; funktiert ja."
STK500-Besitzer schrieb:> Weil der Compiler "annimmt", dass es sich bei "0" um eine Zahl aus dem> Zielzahlenbereich "uint64_t" handelt?!
Nein, es liegt daran, dass mein Build-Prozeß eine 64-Bit-EXE erzeugt
hat. Ich hatte es nur vergessen, dass ich vor längerer Zeit umgestellt
habe.
Walter T. schrieb:
in, es liegt daran, dass mein Build-Prozeß eine 64-Bit-EXE erzeugt
> hat. Ich hatte es nur vergessen, dass ich vor längerer Zeit umgestellt> habe.
Nein.
Das Literal 0 hat den Typ int, ~0 invertiert die Bits des int, das
Ergebnis ist wieder der Typ int (Promotionsregeln) und hat den Wert -1.
Mit -1 wird dann der uint64_t initialisiert, und dabei wird auf uint64_t
konvertiert.
Walter T. schrieb:> Wie praktisch. Das heißt es funktioniert bei allen Bitbreiten, nur aus> unterschiedlichen Gründen. Kein Wunder, dass man auf Dauer paranoid> wird.
Nein. Streng genommen ist es UB. Integer müssen nicht im 2-er
Kompliment gespeichert werden...
Udo K. schrieb:> Walter T. schrieb:>> Wie praktisch. Das heißt es funktioniert bei allen Bitbreiten, nur aus>> unterschiedlichen Gründen. Kein Wunder, dass man auf Dauer paranoid>> wird.>> Nein. Streng genommen ist es UB. Integer müssen nicht im 2-er> Kompliment gespeichert werden...
Seit C23 ist 2'er-Komplement verpflichtend.
Ich würde mit einer dieser beiden Lösungen arbeiten. Letztere ist
vermutlich noch eindeutiger, während man bei der ersten beim Ändern der
Datentypbreite die Zuweisung nicht ändern muss. Beim zweiten schreit in
dem Fall aber hoffentlich irgendein Linter oder compiler ;)
Peter D. schrieb:> uint64_t ullValue = -1;Simon schrieb:> UINT64_MAX
Udo K. schrieb:> Wilhelm M. schrieb:>> Seit C23 ist 2'er-Komplement verpflichtend.>> Das nützt dir nur heute nichts.
Doch (bei gcc): -std=c2x
Zitat cppreference:
Prior to C23, the C Standard allowed any signed integer representation,
and the minimum guaranteed range of N-bit signed integers was from
(e.g. -127 to 127 for a signed 8-bit type), which corresponds to the
limits of one's complement or sign-and-magnitude.
However, all popular data models (including all of ILP32, LP32, LP64,
LLP64) and almost all C compilers use two's complement representation
(the only known exceptions are some compliers for UNISYS), and as of
C23, it is the only representation allowed by the standard, with the
guaranteed range from
(e.g. -128 to 127 for a signed 8-bit type).
Mit einem UB, was in der Tat heute(!) nicht auftritt, kann ich gut
leben.
Wilhelm M. schrieb:> Udo K. schrieb:>> Nein. Streng genommen ist es UB. Integer müssen nicht im 2-er>> Kompliment gespeichert werden...>> Seit C23 ist 2'er-Komplement verpflichtend.
Hallo,
heißt das in Zukunft darf man auf signed Überläufen vertrauen wie man
unsigned Überläufen vertrauen darf?
Veit D. schrieb:> Wilhelm M. schrieb:>> Udo K. schrieb:>>> Nein. Streng genommen ist es UB. Integer müssen nicht im 2-er>>> Kompliment gespeichert werden...>>>> Seit C23 ist 2'er-Komplement verpflichtend.>> Hallo,>> heißt das in Zukunft darf man auf signed Überläufen vertrauen wie man> unsigned Überläufen vertrauen darf?
Nein, das bleibt UB.
Wilhelm M. schrieb:>> heißt das in Zukunft darf man auf signed Überläufen vertrauen wie man>> unsigned Überläufen vertrauen darf?>> Nein, das bleibt UB.
Hast du da eine Referenz? Was wäre sonst der Sinn dahinter?
Wilhelm M. schrieb:>> Das nützt dir nur heute nichts.>> Doch (bei gcc): -std=c2x
Die gcc Homepage meint dazu:
A further version of the C standard, known as C2X, is under
development;
experimental and incomplete support for this is enabled with -std=c2x.
Aber ich kenne keine aktuelle CPU, die nicht 2-er Kompliment hat, von
daher ist die Diskussion sinnlos...
Hallo,
Schade das es nicht konsequent umgesetzt wird. Das würde viele Probleme
beheben. Darf ich fragen was ein Trap ist?
> ... representation (typically 2's complement), it may trap on some> platforms or due to compiler options (e.g. -ftrapv in GCC and Clang) ...
Veit D. schrieb:> Hallo,>> Schade das es nicht konsequent umgesetzt wird. Das würde viele Probleme> beheben. Darf ich fragen was ein Trap ist?>> ... representation (typically 2's complement), it may trap on some>> platforms or due to compiler options (e.g. -ftrapv in GCC and Clang) ...
Ein trap ist ein Software-Interrupt, was das genau bedeutet, ist dann
eben sehr plattformspezifisch. Auf x86/*nix wird dem Prozess ein SIGABRT
gesendet.