Hallo zusammen, kann mir mal jemand bitte die folgende Notation erklären ??? TCNT0 = (uint8_t)(int16_t)-(F_CPU / 1024 * 10e-3 + 0.5); // preload for 10ms Ich nehme an, (uint8_t) ist ein CAST, aber was ist dann (int_16t) ?? Noch ein CAST ? Wo ist denn die Variable, die ich caste ??? Bitte mich nicht zereissen - ich übe noch ...! Vielen Dank
Charly Grosse wrote: > Hallo zusammen, > > kann mir mal jemand bitte die folgende Notation erklären ??? > > TCNT0 = (uint8_t)(int16_t)-(F_CPU / 1024 * 10e-3 + 0.5); // preload for > 10ms > > Ich nehme an, (uint8_t) ist ein CAST, aber was ist dann (int_16t) ?? > Noch ein CAST ? Genau > Wo ist denn die Variable, die ich caste ??? Es gibt keine Variable. Braucht es auch nicht. Ein Cast wandelt den Datentyp eines Ausdrucks in einen anderen Datentyp um. In deinem Fall ist der Ausdruck -(F_CPU / 1024 * 10e-3 + 0.5) und dieser Ausdruck liefert ja ein Ergebnis, welches einen Datentyp besitzt (welchen?).
> > -(F_CPU / 1024 * 10e-3 + 0.5) > > und dieser Ausdruck liefert ja ein Ergebnis, welches > einen Datentyp besitzt (welchen?). Also ich tippe mal, dass der Compiler hieraus ein Float macht. (14.745.600,00 / 1024 * 0,001 + 0,5 liefert mir -14,9 (int16_t) - 14,9 liefert dann für mich -14 (uint8_t) -14 liefert ... tja was ? Hier müsste ich mich erst einmal einlesen. Wie geht´s bitte weiter ?
Charly Grosse wrote: >> >> -(F_CPU / 1024 * 10e-3 + 0.5) >> >> und dieser Ausdruck liefert ja ein Ergebnis, welches >> einen Datentyp besitzt (welchen?). > > Also ich tippe mal, dass der Compiler hieraus ein Float macht. Fast. Es ist ein double. Wenn nichts anderes angegeben, dann ist * eine Zahl ohne einen Dezimalpunkt ein int (mit einer Ausnahme: Ist die Zahl zu gross für einen int dann ist sie vom Typ long) * eine Zahl mit einem Dezimalpunkt ein double > > (14.745.600,00 / 1024 * 0,001 + 0,5 liefert mir -14,9 > > (int16_t) - 14,9 liefert dann für mich -14 > > (uint8_t) -14 liefert ... tja was ? Jetzt musst du auf das Bitpattern zurückgreifen. Das 16 Bit Bitpattern für +14 wäre 0000 0000 0000 1110 Das 16 Bit Bitpattern für -14 ist daher 1111 1111 1111 0010 (alle Bits der positiven Zahl umdrehen (0->1, 1->0) und noch 1 addieren) der cast nach uint8_t schneidet davon erst mal die obersten 8 Bit weg, damit noch 8 Bit übrig bleiben 1111 0010 und dieses Bit Pattern wird jetzt als unsigned Zahl gesehen, also als Zahl ohne Vorzeichen. Welche Zahl ist das? Das ist das Bit-Pattern für die unsigned Zahl 242
Karl heinz Buchegger wrote: > Charly Grosse wrote: >>> >>> -(F_CPU / 1024 * 10e-3 + 0.5) >>> >>> und dieser Ausdruck liefert ja ein Ergebnis, welches >>> einen Datentyp besitzt (welchen?). >> >> Also ich tippe mal, dass der Compiler hieraus ein Float macht. > > Fast. Es ist ein double. > Wenn nichts anderes angegeben, dann ist > * eine Zahl ohne einen Dezimalpunkt ein int > (mit einer Ausnahme: Ist die Zahl zu gross für einen int > dann ist sie vom Typ long) > > * eine Zahl mit einem Dezimalpunkt ein double > >> >> (14.745.600,00 / 1024 * 0,001 + 0,5 liefert mir -14,9 >> >> (int16_t) - 14,9 liefert dann für mich -14 >> >> (uint8_t) -14 liefert ... tja was ? > > > Jetzt musst du auf das Bitpattern zurückgreifen. > Das 16 Bit Bitpattern für +14 wäre > > 0000 0000 0000 1110 > > Das 16 Bit Bitpattern für -14 ist daher > > 1111 1111 1111 0010 > > (alle Bits der positiven Zahl umdrehen (0->1, 1->0) und noch 1 > addieren) > > der cast nach uint8_t schneidet davon erst mal die obersten > 8 Bit weg, damit noch 8 Bit übrig bleiben > > 1111 0010 > > und dieses Bit Pattern wird jetzt als unsigned Zahl gesehen, also > als Zahl ohne Vorzeichen. Welche Zahl ist das? > > Das ist das Bit-Pattern für die unsigned Zahl 242 Super - vielen Dank, das habe ich verstanden. Misstrauisch wie ich bin, habe ich aber mal mit einem kleinen Wizzard nachrechnen lassen, was bei 10 ms (siehe Kommentar "preload for 10 ms" in der Code Zeile) im TCNTx stehen müsste: Laut wizzard 112 Habe ich nun Äpfel mit Birnen verglichen - unterscheidliche Timer Modes ? Das beispiel oben stammt von Peter Danneger zum Tasten Entprellen Im hauptprogramm wurde Timer so gesetzt: TCCR0 = (1<<CS02)|(1<<CS00); // divide by 1024 TIMSK = 1<<TOIE0; // enable timer interrupt Man, ist das für einen Anfänger kompliziert!!!
Sorry, Screenshot vom wizzard war angehängt - habe ich vergessen zu erwähnen ...
Charly Grosse wrote: > Super - vielen Dank, das habe ich verstanden. Misstrauisch wie ich bin, > habe ich aber mal mit einem kleinen Wizzard nachrechnen lassen, was bei > 10 ms (siehe Kommentar "preload for 10 ms" in der Code Zeile) > im TCNTx stehen müsste: Laut wizzard 112 Ja, da kann der Kommentar nichts dafür, wenn Du die Formel änderst: 0,0001s = 1ms !!! Und der Wizzard sollte natürlich für 1ms und 10ms unterschiedliche Werte ausgeben. Peter
Peter Dannegger wrote:
> 0,0001s = 1ms !!!
Eine Null zu viel...
Peter Dannegger wrote: > Charly Grosse wrote: > >> Super - vielen Dank, das habe ich verstanden. Misstrauisch wie ich bin, >> habe ich aber mal mit einem kleinen Wizzard nachrechnen lassen, was bei >> 10 ms (siehe Kommentar "preload for 10 ms" in der Code Zeile) >> im TCNTx stehen müsste: Laut wizzard 112 > > Ja, da kann der Kommentar nichts dafür, wenn Du die Formel änderst: > > > 0,0001s = 1ms !!! > > > Und der Wizzard sollte natürlich für 1ms und 10ms unterschiedliche Werte > ausgeben. > > > Peter Ich will ja nicht Recht haben ... aber : die Zeile des Programms ist original dem Code entnommen - nix geändert - jedenfalls nich wissentlich. Und es gilt immer noch: 1s = 1000ms 0,1s = 100ms 0,01s = 10ms 0,001s = 1ms Der wizzard sagt, dass im Kommentar dann wohl eher 1 ms sehen muss. Aber Hauptsache, das Programm funzt ... wirklich super ! Vielen Dank ! Ich will ja nicht Recht bekommen, sondern nur verstehen. Grüsse
Charly Grosse wrote: > die Zeile des Programms ist original dem Code entnommen - nix geändert - > jedenfalls nich wissentlich. Die original Zeile steht ja im 1. Post:
1 | TCNT0 = (uint8_t)(int16_t)-(F_CPU / 1024 * 10e-3 + 0.5); // preload for 10ms |
und 10 * 1e-3 ist immer noch 0,01. Das weiß sogar der Compiler. Der Kommentar stimmt da also noch. Peter
Mann, Peter "1E-3" gibt es nicht. Es stand auch 10E3 da, und das ist klar 0,001. Wer lesen kann ist klar im Vorteil, und wer immer so leicht mit übler Kritik bei der Hand ist sollte gründlicher lesen. Gruss Skeptiker
@Skeptiker > "1E-3" gibt es nicht. > Es stand auch 10E3 da, und das ist klar 0,001. Ach, mein gcc ist da aber ganz anderer Meinung.
1 | #include <stdio.h> |
2 | |
3 | int main () { |
4 | |
5 | float f1 = 1e-3; |
6 | float f2 = 10e-3; |
7 | |
8 | printf("%1.4f\n%1.4f\n",f1,f2); |
9 | }
|
Output: 0.0010 0.0100
Skeptiker wrote: > "1E-3" gibt es nicht. > Es stand auch 10E3 da, und das ist klar 0,001. Meinst Du wirklich, alle C-Programmierer sind Idioten? > Wer lesen kann ist klar im Vorteil, > und wer immer so leicht mit übler Kritik bei der Hand ist > sollte gründlicher lesen. Und warum tust Du es dann nicht und liest mal ein C-Buch? 1E-3 10E3 10E-3 sind alles gültige C-Syntax für float-Zahlen. Peter
@Peter Mist. Hast recht. Hätte Dir so gerne mal eins reingewürgt. Na dann ein andermal. Gruss Skeptiker
... jetzt kenne ich auch den Unterschied zwischen einem Mathematiker und einem Informatiker ... Mathematiker: 10E-3 = 0,001 Informatiker: 1E-3 = 0,001 Fortran wurde noch von den Mathematikern erdacht, C wahrscheinlich von einem Informatiker ...! Grüsse
Charly Grosse wrote: > ... jetzt kenne ich auch den Unterschied zwischen einem Mathematiker und > einem Informatiker ... > > Mathematiker: 10E-3 = 0,001 In Mathematiker würde sowas niemals sagen. Für ihn würde das maximal "10 mal e hoch -3" bedeuten. Ein Mathematiker würde maximal sagen "10 mal 10 hoch -3", sofern er überhaupt 10-er Potenzen benutzt. Mathematiker 'rechnen' nämlich im arithmetischen Sinn eher wenig. > Informatiker: 1E-3 = 0,001 Da man in einer Programmiersprache "mal 10 hoch" eher schlecht schreiben kann, wurde für diese feststehende, fixe Phrase das Zeichen 'E' eingeführt. 1E-3 liest sich ganz einfach als "1 mal 10 hoch -3" > > Fortran wurde noch von den Mathematikern erdacht, Ich muss dich enttäuschen. Die 'E' Schriibweise war auch in Fortran schon so. Und da sie sich bewährt hat, hat man sie über all die Jahre beibehalten. > C wahrscheinlich von > einem Informatiker ...! Eher von 2 Bastlern, die einen ausrangierten, nicht benutzen Computer fanden und sich in den Kopf setzten dafür ein Betriebs- system zu schreiben. Nachdem ihr erster Ansatz in Assembler aber nicht so der große Wurf war, kreierten sie ihre eigene Sprache: B die sich im Lauf der Zeit zu C entwickelte http://cm.bell-labs.com/cm/cs/who/dmr/chist.html
ist glaub ich standard für float zahlen $ ruby -e 'puts 10e-1' 1.0 $ python -c 'print 1e3' 1000.0 $ perl -e '$x=1e3; printf "$x \n"' 1000 octave:1> 1e3 ans = 1000 usw ;) ich wollte allen ernstes in der letzten klausur mir die längeren 1.234*10^-8 ausdrücke ersparen und durch kürzere 1.234e-8 ersetzen .. habe es aber dann doch gelassen :)
> >> >> Fortran wurde noch von den Mathematikern erdacht, > > Ich muss dich enttäuschen. Die 'E' Schriibweise war auch in > Fortran schon so. Und da sie sich bewährt hat, hat man sie über > all die Jahre beibehalten. > >> C wahrscheinlich von >> einem Informatiker ...! > Ich meine mich aber zu erinnern, dass in der Fortran Notation aber mindestens die Zahl vor dem Buchstaben "E" oder "e" eine FLOAT Schreibweise haben musste (also z.b. 1.E-3) - stimmt's ? Eine Integer Notation habe ich nicht vor Augen Auf jeden Fall bin ich froh, dass ich was in der Timer Einstellung verstanden habe - Grüsse
Charly Grosse wrote: > Ich meine mich aber zu erinnern, dass in der Fortran Notation aber > mindestens die Zahl vor dem Buchstaben "E" oder "e" eine FLOAT > Schreibweise haben musste (also z.b. 1.E-3) - stimmt's ? An so eine Einschränkung kann ich mich nicht erinnern. Und ich habe viel technisches Zeugs in Fortran programmiert. Auf diesen Fall hab ich übrigens ziemlich weit oben vergessen > Wenn nichts anderes angegeben, dann ist > * eine Zahl ohne einen Dezimalpunkt ein int > (mit einer Ausnahme: Ist die Zahl zu gross für einen int > dann ist sie vom Typ long) > > * eine Zahl mit einem Dezimalpunkt ein double * eine Zahl in der Schreibweise Zahl E Zahl (also die Notation um die es jetzt geht), ist ebenfalls ein double
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.