Forum: Mikrocontroller und Digitale Elektronik 32BIT unsigned int auf 16Bit uP?


von Globi (Gast)


Lesenswert?

Hallo

Kann mir jemand sagen wie ich eine 32Bit Variable definieren muss damit 
dies dann über den Compiler auf einem 16Bit uP läuft?
Ich arbeite mit dem PIC24FJ128 und dem Compiler MPC30.

Mit diesem Code bekomme ich 0x0000FFFF als Ausgabe, sollte aber 
0xFFFFFFFF sein...


long unsigned int test = 0xFFFFFFFF;
printf("test = %.8X \n\r", test);



Danke

von (prx) A. K. (prx)


Lesenswert?

printf("test = %.8lX \n\r", test);

von Globi (Gast)


Lesenswert?

A. K. schrieb:
> printf("test = %.8lX \n\r", test);

Ok, passt so, vielen Dank, aber für was steht die 1?

von Floh (Gast)


Lesenswert?

l "el" für long :-)

von Globi (Gast)


Lesenswert?

ok, danke

von Thosch (Gast)


Lesenswert?

Globi schrieb:

> Ok, passt so, vielen Dank, aber für was steht die 1?
Nein, das ist keine Eins, das ist ein kleines "L".
und das steht für Long.

Gruß,
Thorsten

von Thosch (Gast)


Lesenswert?

upps, zu langsam...

von Globi (Gast)


Lesenswert?

danke @ all für die schnellen Antworten, hatte schon Zweifel am 
Compiler...

von Karl H. (kbuchegg)


Lesenswert?

Globi schrieb:
> danke @ all für die schnellen Antworten, hatte schon Zweifel am
> Compiler...

Du solltest eher Zweifel an deinem C-Buch haben.
Ooops. Du hast gar keines?
Na, da haben wirs doch!

von Alfred (Gast)


Lesenswert?

Hallo Globi,

ich kenne Deinen Compiler nicht, aber beim GCC kann man mit den 
(Kommandozeilen) Parametern -Wall -Werror veranlassen, dass der Compiler 
ALLE Warnungen als Fehler behandelt und den Übersetzungsvorgang 
abbricht. Bei Deinem Problem hätte Dir dann der Compiler gesagt, dass 
das Format '%.8X' nicht zu dem Parameter 'test' passt.

Nur so als Hinweis ;-)

Beste Grüße

Alfred

von Peter (Gast)


Lesenswert?

long unsigned int test = 0xFFFFFFFF;  // ??? finde ich lustig!
unsigned long test     = 0xFFFFFFFF;  // is wohl besser so...

von Thosch (Gast)


Lesenswert?

Long-Konstanten sollte man übrigens auch besser mit angehängtem
L (signed long) bzw. UL (unsigned long) definieren.
also z.B.:
1
unsigned long test = 0xFFFFFFFFUL;

Viele Compiler werfen 'ne Warning "Constant is long" oder ähnlich, wenn 
man's nicht tut...

Gruß,
Thorsten

von (prx) A. K. (prx)


Lesenswert?

Peter schrieb:

> long unsigned int test = 0xFFFFFFFF;  // ??? finde ich lustig!
> unsigned long test     = 0xFFFFFFFF;  // is wohl besser so...

Ist exakt gleichwertig.

von (prx) A. K. (prx)


Lesenswert?

Thosch schrieb:

> Viele Compiler werfen 'ne Warning "Constant is long" oder ähnlich, wenn
> man's nicht tut...

Welcher Compiler ist "viele"?
Halte ich nämlich nicht für eine brilliante Idee.

von Oleg (Gast)


Lesenswert?

A. K. schrieb:
> Thosch schrieb:
>
>> Viele Compiler werfen 'ne Warning "Constant is long" oder ähnlich, wenn
>> man's nicht tut...
>
> Welcher Compiler ist "viele"?

Ich kenne es auch vom AVR-GCC.

> Halte ich nämlich nicht für eine brilliante Idee.

Warum ?

von (prx) A. K. (prx)


Lesenswert?

Oleg schrieb:

> Ich kenne es auch vom AVR-GCC.

gcc auf 64-bit Linux sagt es in einem vergleichbaren Fall nicht.

> Warum ?

Portabilität.

Dadurch werden Daten und Rechnungen unnötig aufgeblasen. Wenn auf einer 
Maschine mit sizeof(long)=4 und sizeof(int)=2 alle Konstanten >int mit L 
oder UL versehen werden, dann kriegt man in einer Umgebung mit 
sizeof(long)=8 und sizeof(int)=4 unnötigerweise 64bit-Werte und 
Berechnungen. Und anschliessend wundert sich der sensibel eingestellte 
Compiler, dass er die in eine 32bit Variable schreiben soll (weil man 
uint32_t verwendet hat).

Letztlich müsste man dann konsequenterweise überall sowas grausliches 
hinschreiben wie:
  ((uint32_t)0xFFFFFFFFuL)

Im Kontext von Mikrocontroller ist das zwar noch nicht relevant, aber es 
gibt ja auch andere Umgebungen.

von (prx) A. K. (prx)


Lesenswert?

Oleg schrieb:

> Ich kenne es auch vom AVR-GCC.

Hast du ein Beispiel? Ich finde grad keines mit so einer Meldung.

von Andreas F. (aferber)


Lesenswert?

Bei Angabe der Konstanten in Hex-Form fällt mir hier jetzt auf Anhieb 
auch kein problematischer Punkt ein.

Eine subtile Falle kann allerdings bei bestimmten dezimalen Konstanten 
lauern (Beispiel auf x86, also mit 32 Bit long):
1
#include <stdio.h>
2
3
long long i = -2147483648;
4
5
int main(void)
6
{
7
        printf("%lld\n", i);
8
        return 0;
9
}
1
% gcc -std=iso9899:1990 -g -O2 -W -Wall -o large large.c
2
large.c:3: warning: this decimal constant is unsigned only in ISO C90
3
% ./large
4
2147483648
5
% gcc -std=iso9899:1999 -g -O2 -W -Wall -o large large.c
6
% ./large
7
-2147483648

"long long" ist hier natürlich im C90-Fall eine GCC-Erweiterung, 
nichtsdestotrotz ist das Ergebnis "überraschend".

Der Hintergrund ist, dass es in ANSI-C eigentlich keine negativen 
Konstanten gibt. "-2147483648" ist die Konstante "2147483648", auf die 
dann eine Negation angewendet wird. In C90 ist "2147483648" nicht mehr 
in einem long darstellbar (soweit long 32 Bits hat), daher ist das dann 
ein unsigned long, und auch die Negation wird dann mit unsigned long 
gerechnet (so unsinnig das auch erstmal klingen mag), das Ergebnis 
bleibt positiv. In C99 wird dagegen auf long long (minimal 64 Bits) 
statt unsigned long zurückgegriffen, daher führt dann die Negation auch 
wirklich zu einem negativen Wert.

Andreas

von fragender (Gast)


Lesenswert?

>long unsigned int test = 0xFFFFFFFF;

????????
Ist das zulässig bzw. sinnvoll?

von (prx) A. K. (prx)


Lesenswert?

fragender schrieb:

> Ist das zulässig bzw. sinnvoll?

Weshalb sollte es das nicht sein?

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.