Forum: Mikrocontroller und Digitale Elektronik unsigned long int Berechnung


von HaPe (Gast)


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?

von Mike R. (thesealion)


Lesenswert?

Wie wäre es, wenn du mal deine Rechnung zeigst.

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

HaPe schrieb:
> 64-bit signed type.
Wofür?

von HaPe (Gast)


Lesenswert?

uintmax_t x = 12;

void main(void)
{

DDRD = 0xFF;
PORTD = 0xFF;

x = 9993 * 7;

}

Das Programm ist nur zum testen

Ergebniss x = 4415

von HaPe (Gast)


Lesenswert?

64-bit signed type nutze ich nicht....hab das nur so aus der header 
Datei kopiert

ich brauche nur einen 32-bit unsigned typ

kann es sein das der Atmega 8 sowas nicht berechnen kann

von THaala (Gast)


Lesenswert?

Hi,

versuch mal
x = (uintmax_t)9993 * (uintmax_t)7;

Gruß

von eProfi (Gast)


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.

von Peter D. (peda)


Lesenswert?

THaala schrieb:
> versuch mal
> x = (uintmax_t)9993 * (uintmax_t)7;

Nö, 64Bit ist nur Verschwendung.

So gehts:
1
uint32_t x;
2
3
x = 9993 * 7UL;


Peter

von Falk B. (falk)


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

von HaPe (Gast)


Lesenswert?

jawoll das geht...warum ist das casting nötig?

von HaPe (Gast)


Lesenswert?

Hey Falk das hab ich alles probiert...brachte aber keinen Erfolg

von Falk B. (falk)


Lesenswert?

@  HaPe (Gast)

>Hey Falk das hab ich alles probiert...brachte aber keinen Erfolg

Glaub ich nicht.

von Willi (Gast)


Lesenswert?


von HaPe (Gast)


Lesenswert?

Danke für eure Hilfe

hat mir sehr geholfen!!!!

von eProfi (Gast)


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.

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.