www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Warum rechnet mein mega 8 falsch


Autor: Herrmann (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo

habe folgende funktion.



void rechne(void)
{
int ergebniss=2^10;
sprintf(buffer,"ergebniss=%d",ergebniss)
//in buffer steht ergebniss=8
//statt 1024



}


warum

Autor: Gast (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
2^10

Was soll denn hier passieren?

Autor: Gast (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Oder das ergebniss hat zuviel Biss und frist den Rest auf?

Autor: scw (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
geht 2^10 überhaupt in C (so wie du willst)? glaub du solltest mal die 
funktion pow ausprobieren :-)
War ^ nicht sowas wie XOR?

Autor: scw (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
2 XOR 10 = 0010 XOR 1010 = 1000 = 8 :-)

Autor: Schwurbl (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Geil, ich hab's auch nicht bemerkt. Sollte mir nen Kaffe machen... :-)

Autor: Herrmann (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
gar nichts habe ein probkem mit einen drucksensor

dort werden berechnungen gemacht um den druck zu errechnen.


z.b

sems=26051+822*170/2^10+24576

26051 lese ich vom sensor
die 822 auch.

in excel bekomme ich 50763 wie es sein soll
der avr bringt 5819

warun

Autor: scw (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
siehe oben... das zeichen ist nicht das exponenten-zeichen sondern steht 
für xor. Einfach mal pow anstatt ^ benutzen.

Autor: GastABC (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Weil ^ in C nicht Hoch, sondern XOR bedeutet.

Schreib statt 2^10 einfach 1024 und es sollte wunderbar laufen :)

Autor: Herrmann (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
pow(2,10) ergibt 800.


Also irgendwas stimmt nicht

Autor: Herrmann (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Sorry  400 in hex sind dez =1024

geht doch

jetzt probiere ich es mit der ganzen formel

Autor: Peter Dannegger (peda)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
2 hoch ist schieben, also

1<<10 == 1024

Du solltest mal ein C-Buch zur Hand nehmen.


Peter

Autor: Schwurbl (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Du gibst das Ergebnis aber schon so aus:

sprintf(Buffer("X = %d",(int)pow(2,10));

Autor: Schwurbl (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Also der Typecast nach int, damit es mit %d zusammmenpasst

Autor: Herrmann (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich begreife es nicht


wenn ich (822*170)/pow(2,10)

bekomme ich 8

das kann doch nicht sein

Autor: Johannes M. (johnny-m)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
822 * 170 = 139740
-> 0x221DC
--> (int)0x221DC = 0x21DC (= 8668)
8668 / 2^10 = 8 (Rest 476)

Merke: In einen int passen nur Zahlen von -32768...32767 rein.

BTW: In C werden zunächst alle Berechnungen in int durchgeführt, es 
sei denn, ein Operand besitzt einen größeren Datentyp oder man gibt dem 
Compiler explizit an, dass er die Berechnung in einem erweiterten 
Wertebereich durchführen soll (Suffixe L, UL, Zahlen in 
Gleitkommadarstellung o.ä.).

Autor: Wolfgang Mües (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Herrmann,

> wenn ich (822*170)/pow(2,10)
> bekomme ich 8

vielleicht solltest Du Dich erst einmal näher mit den Regeln der 
Ganzzahl-Arithmetik beschäftigen. Dann hast Du nicht so viel Frust, und 
die Ergebnisse werden auch besser.

Zunächst einmal: pow(2,10) macht niemand. Wozu die Rechenzeit 
investieren, wenn man das Ergebnis auch hinschreiben kann? Also 1024 
stattdessen.

Zweitens: Du hast bei ganzen Zahlen nur einen beschränkten Wertebereich.
822 * 170 sollte nach Deiner Meinung 139740 ergeben. Wenn ein int(eger) 
aber 16 bit ist, dann bekommst Du einen Überlauf, und das Ergebnis 
modulo 2 hoch 16 (=65536). Das ergibt dann 8668. Und wenn Du 8668 durch 
1024 teilst, dann kommt 8,46... raus. Und da wir mit ganzen Zahlen 
rechnen, eben die 8.

Du hast jetzt 2 Alternativen:

a) Du kannst mit Fließkomma rechnen. Dauert länger, ist aber u.U. 
vertretbar. Fließkomma hat den Datentyp "float" und eine Fließkomma-Zahl 
ist alles, was einen Punkt in der Zahl hat. Also eine Konstante "12" ist 
eine Festkommazahl, eine Konstante "12.0" ist eine Fließkommazahl.

b) Du könntest - wenn es Dir auf Geschwindigkeit oder Codegröße oder 
Ehrgeiz ankommt - mit 32bit Festkommazahlen rechnen. Der Datentyp dafür 
lautet "long", und eine long-Konstante erzeugst Du mit "12L".

Nur Mut, es ist nicht wirklich schwer.

Autor: GastABC (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Du kannst auch einfach die Rechnung ein wenig umstellen, dann passt es 
auch wieder:

(822*34) / pow(2,10) * 5

(822*34) passt noch in einen Int
/1024
* 5

du rechnest also in 2 Schritten: erst mal 34, dann mal 5 ergibt zusammen 
mal 170.

Darunter leidet aber deine Auflösung, weil du beim teilen durch 1024 die 
Nachkommastellen verlierst :(

Autor: Herrmann (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Danke

Ich habe leider nur ein C Buch da steht drin das der int ein 32bit 
bereich hat.aber so ist es aber beim avr oder gcc nicht.

Hat jemand ein gutes buch für c und avr wo sawas drin steht????


Danke

Autor: Andreas B. (bitverdreher)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
So etwas vermeidest Du, indem Du gleich die Datentypen
int8_t
int16_t
uint8_t
uint16_t

ect. verwendest.
Ansonsten guckst Du einfach mal hier:
http://www.mikrocontroller.net/articles/AVR-GCC-Tutorial

Gruß
Andy

Autor: Gast (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Merke: In einen int passen nur Zahlen von -32768...32767 rein.

Das stimmt so nicht, das hängt einfach vom Compiler ab.

Autor: Jens (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Powned =)

Autor: Johannes M. (johnny-m)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Gast wrote:
>> Merke: In einen int passen nur Zahlen von -32768...32767 rein.
>
> Das stimmt so nicht, das hängt einfach vom Compiler ab.
Warum können sich gewisse Leute solche überflüssigen Postings nicht 
einfach kneifen? Es ist sonnenklar, dass es hier um AVR-µCs geht, und 
ich kenne keinen Compiler für diese Plattform, bei dem int nicht 16 
Bit breit ist!

Autor: Randy (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Ich habe leider nur ein C Buch da steht drin das der int ein 32bit
> bereich hat.aber so ist es aber beim avr oder gcc nicht.

Dann ist das ein scheiß Buch. Es war schon immer so (C gibt es seit den 
70'ern) dass der Typ int die Lieblings-Wortbreite des verwendeten 
Prozessors hat. Der Autor kann also gar nicht wissen wie Breit ein int 
ist. Bei den heute üblichen PC-Prozessoren sind das 32 Bit, da hat der 
Autor schon recht. Vor ein paar Jahren (DOS/Win3.1 evtl. noch Win95/98) 
waren es typischerweise 16 Bit. 32 hätten die CPUs ab 386 schon gekonnt, 
die Standard-int breite wurde aber lange für die Programmierer 
beibehalten die sich drauf verlassen hatten dass ein int immer 16 Bit 
breit ist. Und es gab ein paar Großrechner mit so krummen Sachen wie 13 
oder 18 Bit. Und gerade C wird eben nicht nur für PCs benutzt.

Randy

Autor: Michael König (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Ich habe leider nur ein C Buch da steht drin das der int ein 32bit
> bereich hat.

Dann empfehle ich stattdessen "The C Programming Language" von Kernighan 
& Ritchie.

Im Standard ist eigentlich festgelegt, daß "short" 16 Bit hat und "long" 
32 Bit. Wie Randy schon schreibt, ist "int" Compiler-abhängig, d.h. der 
Compiler nimmt entweder "short" oder "long" dafür.

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.