Forum: Compiler & IDEs Casting - Aller Anfang ist schwer


von John S. (student)


Lesenswert?

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

von Karl H. (kbuchegg)


Lesenswert?

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?).

von John S. (student)


Lesenswert?

>
>     -(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 ?

von Karl H. (kbuchegg)


Lesenswert?

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

von John S. (student)


Angehängte Dateien:

Lesenswert?

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!!!

von John S. (student)


Lesenswert?

Sorry, Screenshot vom wizzard war angehängt - habe ich vergessen zu 
erwähnen ...

von Peter D. (peda)


Lesenswert?

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

von Johannes M. (johnny-m)


Lesenswert?

Peter Dannegger wrote:
> 0,0001s = 1ms !!!
Eine Null zu viel...

von John S. (student)


Lesenswert?

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

von Peter D. (peda)


Lesenswert?

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

von Skeptiker (Gast)


Lesenswert?

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

von Skeptiker (Gast)


Lesenswert?

Es stand natürlich 10E-3 da.

von Stefan E. (sternst)


Lesenswert?

@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

von Peter D. (peda)


Lesenswert?

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

von Skeptiker (Gast)


Lesenswert?

@Peter

Mist. Hast recht. Hätte Dir so gerne mal eins reingewürgt.
Na dann ein andermal.

Gruss
Skeptiker

von John S. (student)


Lesenswert?

... 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

von Karl H. (kbuchegg)


Lesenswert?

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

von daniel (Gast)


Lesenswert?

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 :)

von John S. (student)


Lesenswert?

>
>>
>> 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

von Karl H. (kbuchegg)


Lesenswert?

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
Noch kein Account? Hier anmelden.