unsigned long int Berechnung

Gast #2177513
Lesenswert?

Hallo zusammen,

ich benutze einen Atmega 8 und das AVRStudio4

Nun muss ich z.b 9993 * 123 rechnen...damit überschreite ich ja die 
16bit vom unsigned int.

also deklariere ich meine Variable mit "unsigned long int"
leider kommen dabei nur brauchbare Ergebnisse bis 2^15 raus.

In der stint.h steht:

 typedef unsigned long int uint32_t;

/** \ingroup avr_stdint
    64-bit signed type.
    \note This type is not available when the compiler
    option -mint8 is in effect. */

Jetzt hab ich Folgendes in mein Programm geschrieben

#if __USING_MINT8
typedef int32_t intmax_t;

typedef uint32_t uintmax_t;
#else  /* !__USING_MINT8 */
/** \ingroup avr_stdint
    largest signed int available. */

typedef int64_t intmax_t;

/** \ingroup avr_stdint
    largest unsigned int available. */

typedef uint64_t uintmax_t;
#endif /* __USING_MINT8 */


aber leider bringt das auch nicht...

was mache ich falsch?
Gast #2177539
Lesenswert?

Da Problem ist, dass der Compiler zuerst mal rechts nur int sieht und 
dann auch int multipliziert.
Dann sieht er links 32 bits, und macht einen Cast.

Du musst ihm also klarmachen, dass die Mul schon 32 bits haben soll, 
indem mindestens ein Operand long ist.

z.B. mit
m = 9993 * 123L;    oder
m = (long)9993*123;

Aber aufpassen, manchmal reicht einmal es nicht, z.B.
m = 9993 * 123L + 1234 * 5678;  geht nicht, da erst beide Muls 
ausgeführt werden (die rechte mit 16 Bit) und dann addiert wird.
#2177542
Lesenswert?

@HaPe (Gast)

>Nun muss ich z.b 9993 * 123 rechnen...damit überschreite ich ja die
>16bit vom unsigned int.

http://www.mikrocontroller.net/articles/Festkommaarithmetik#Die_L.C3.B6sung

>also deklariere ich meine Variable mit "unsigned long int"

Nimm uint32_t, das schreibt sich nicht nur kürzer, ist auch klar 
definiert.

>Jetzt hab ich Folgendes in mein Programm geschrieben

Solche krypischen Sachen sind meist nicht sinnvoll.
Zumal sie hier am Problem vorbeigehen.

MFG
Falk
Gast #2177987
Lesenswert?

Besonders gemein ist folgender Fall:
unsigned long m = 123 * 456;

Das mathematische Ergebnis 56088 (0xdb18) hat nur 16 Bits, aber: da der 
Compiler (wenn nichts anderes angegeben ist) von signed int ausgeht, 
wird auch das Ergebnis als signed int interpretiert.

Dann wird auf 32 Bit erweitert, und zwar sign extended!
Es kommt also ganz unerwartet 4294957848 (0xffffdb18) heraus.

Eine weitere Lösung ist
m  = 1234;
m *= 5678;

Das sind typische Anfängerfehler, über die jeder mal stolpert.
Am besten überall die Größe angeben.

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