STM32, Bedeutung 1UL = unsigned long mit Wert 1 ?

Gast #3006512
Lesenswert?

Hallo,

ich bin von den 8Bit Atmel auf den 32Bit STM32 (Keil Compiler) 
umgestiegen.
Ich finde in den Programmen immer wieder solche Sachen wie 1UL.

Was ich bisher schon herausgefunden habe ist, dass das UL wohl unsigned 
long bedeutet, aber der Wert davor, die Funktion der Zahl 1 ist mir 
nicht ganz klar. Heist das, dass die Zahl den Wert 1 hat, aber der Typ 
ein unsigned long ist?

Gruß Matthias
#3006565
Lesenswert?

Matthias W. schrieb:
> Heist das, dass die Zahl den Wert 1 hat, aber der Typ
> ein unsigned long ist?

Genau. Ohne Typangabe sind Konstanten vom Typ int. Das kann in manchen 
Rechenoperationen einen Unterschied machen.

Beispiel: Auf einem AVR ist ein int 16 Bit breit, ein long 32 Bit.

1         ist 0b0000000000000001
1 << 15   ist 0b1000000000000000
1 << 16   ist 0b0000000000000000
~1        ist 0b1111111111111110

1UL       ist 0b00000000000000000000000000000001
1UL << 15 ist 0b00000000000000001000000000000000
1UL << 16 ist 0b00000000000000010000000000000000
~1        ist 0b11111111111111111111111111111110

Wenn man also sicher gehen möchte, dass bei solchen Berechnungen die 
vollen 32 Bit genutzt werden, nimmt man 1UL. In der Praxis würde bei 
einem STM32 auch einfach 1 reichen, da ein int auf der Plattform 32 Bit 
breit ist. Es ist aber sauberer, wenn man darüber im Code keine Annahmen 
macht und explizit 1UL schreibt, wenn man 32 Bit braucht.
Gast #3014775
Lesenswert?

Matthias W. schrieb:
> Ich finde in den Programmen immer wieder solche Sachen wie 1UL.

Nun, du hast schon das Richtige herausgefunden. Aber sowas wie 1UL ist 
eigentlich völlig überflüssiger Krempel. Kein heutiger Compiler braucht 
sowas - schon garnicht in der 32 Bit Welt. Das sind alles nur Altlasten 
aus den blutigen Anfängen von C.

Manchmal passiert es einem bei der Definition von Konstanten, daß man 
über Bit 30 hinausrutscht und dann meckert der Compiler, z.B. bei sowas:

#define PortA_Mode 3
#define PINSEL1  (PortA_Mode<<30) | (blablabla...)

In solchen Fällen schafft ein gezielter Typecast (unsigned long) das 
Problem aus der Welt.

W.S.
#3014844
Lesenswert?

S. K. schrieb:
>> Notation 1.0L-6
>
> Könnte mir das bitte jemand deuten?

1.0E-6, aber als "long double" statt "double". Der Witz daran ist, dass 
kein Cast der Welt einmal verlorene Bits wieder hinzufügt. Eine 
Integerkonstante verliert keine Bits, weil der Compiler den Typ stets 
gross genug wählt. Bei Fliesskommakonstanten sieht das anders aus.
#3016464
Lesenswert?

W.S. schrieb:
> Ja. Und es ist Pfusch.

Stimmt, weil 1.0E-6L korrekt ist.

Aber abgesehen davon: Wie würdest du 0.1 als "long double" Konstante 
ausdrücken? (long double)0.1 funktioniert nicht, denn
  0.1L - (long double)0.1
ist
  -0.00000000000000000555L
im 80-Bit-Format. Mir ist kein Weg bekannt, eine lexikalische Konstante 
für "long double" ohne Verlust an Genauigkeit anders anzugeben als mit 
"L" hinten dran.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren