Arduino: Typecast von float nach unsigned int

Gast #5576553
Lesenswert?

Nur mal so gefragt: Wie kann ich einen Typecast von float nach unsigned 
int vornehmen?

einfach so?
1
unsigned int Intvariable;
2
float Floatvariable;
3
Intvariable = Floatvariable;

Eine rundung erfolgt dann vermutlich nach den üblichen Standards.

Was aber, wenn Floatvariable zu groß ist? Gibts dann einen 
Runtime-Error?

Ähm...wie äußert sich ein Runtime-Error auf dem Arduino eigentlich?


***

Und noch eine Zusatzfrage: Bit-Schieben, z.B. '<<' geht mit float nicht, 
oder?
Gast #5576563
Lesenswert?

Roth schrieb:
> Eine rundung erfolgt dann vermutlich nach den üblichen Standards.
>
> Was aber, wenn Floatvariable zu groß ist? Gibts dann einen
> Runtime-Error?
>
> Ähm...wie äußert sich ein Runtime-Error auf dem Arduino eigentlich?

Kauf dir mal ein C++ Buch, dann könntest du dir ein evtl ein paar dumme 
Fragen einsparen und dabei noch viel schneller lernen.

Nachtrag: Bitte!

Konkrete Antwort:
Natürlich erfolgt ein impliziter Cast.
Und da der Kompiler (Programmierer) in so einem Fall von einer Absicht 
ausgeht, gibts auch keinerlei Warnung.

Roth schrieb:
> Runtime-Error

So ein Quatsch...
Es gibt exit() und abort().
Und das wars....
(aber das steht auch alles in dem dicken Buch)
#5576564
Lesenswert?

Roth schrieb:
> Nur mal so gefragt: Wie kann ich einen Typecast von float nach unsigned
> int vornehmen?
>
> einfach so?
>
1
unsigned int Intvariable;
2
> float Floatvariable;
3
> Intvariable = Floatvariable;
>
> Eine rundung erfolgt dann vermutlich nach den üblichen Standards.
>
> Was aber, wenn Floatvariable zu groß ist? Gibts dann einen
> Runtime-Error?
>
> Ähm...wie äußert sich ein Runtime-Error auf dem Arduino eigentlich?
>
>
> ***
>
> Und noch eine Zusatzfrage: Bit-Schieben, z.B. '<<' geht mit float nicht,
> oder?

Hi,

Bits schieben geht bei Fliesskommazahlen nicht. Wenn du dir den Aufbau 
ansiehst, erkennst du auch warum.

Einfach prüfen ob dein Float größer oder gleich 2^16 und ob er kleiner 
als 0 ist.

Gruß JackFrost
#5576569
Lesenswert?

Roth schrieb:
> @ufuf, schlechte Laune schon am frühen Morgen? ;) Das "dicke Buch" kaufe
> ich vielleicht später
> Bastian W. schrieb:
>> Einfach prüfen ob dein Float größer oder gleich 2^16 und ob er kleiner
>> als 0 ist.
> Danke. Was macht denn der Arduino, wenn bei Runtime ein Wert nicht
> passt?

Nein , das solltest du im Programm machen und wenn der Wert von deinem 
Float nicht in einen 16 Bit Integer passt musst du ja wissen was dann in 
der Variable stehen muss.

Gruß JackFrost
#5576580
Lesenswert?

Roth schrieb:
> Nur mal so gefragt: Wie kann ich einen Typecast von float nach unsigned
> int vornehmen?
>
> einfach so?unsigned int Intvariable;
> float Floatvariable;
> Intvariable = Floatvariable;

Das ist kein Cast, sondern einfach eine Zuweisung.

> Eine rundung erfolgt dann vermutlich nach den üblichen Standards.

Was auch immer du mit "den üblichen Standards meinst": Der 
Nachkomma-Anteil wird bei der Konvertierung abgeschnitten.
Gast #5576596
Lesenswert?

Roth schrieb:
> Ist die Frage zu schwer? Dann ziehe ich sie zurück.

Definiere Runtime Error. Es gibt verschiedene Fehlerfälle, die sich 
verschieden äußern. Die meisten Fehler bewirken "undefined behaviour", 
d.h. es passiert irgend etwas, je nachdem worauf Compiler und Prozessor 
gerade Lust haben.
Gast #5576636
Lesenswert?

Typecast, Zuweisung, Rundung - das sind 3 verschiedene Sachen.

Als Anweisungen solltest Du genauestens hinschreiben was Du erreichen 
möchtest, die Nachfrage im Forum ersetzt nicht das sich-auskennen mit 
den vorliegenden Werkzeuge.
(Arduino = verschiedene Versionen für verschiedene CPUs mit 
verschiedenen Crosscompilers)
Gast #5576709
Lesenswert?

Leute, es steht doch oben was er wissen will....

>>>Was passiert wenn man auf unsigned int casted, die variabel jeodch zu groß 
ist<<<

Bastian W. schrieb:
> Nein , das solltest du im Programm machen und wenn der Wert von deinem
> Float nicht in einen 16 Bit Integer passt musst du ja wissen was dann in
> der Variable stehen muss.

Ja, aber was passiert wenn man es eben nicht vorsieht? Gibt es einfach 
nur eine andere Zahl (sowas wie ein overflow?) oder wirft er dann einen 
Fehler aus ( geht in den exit() oder abort() wie schon oben beschrieben) 
und was passiert dann (bleibt stehen, neustart?). Könnte mir vorstellen 
das bei Arduino ein Watchdog aktiv ist, der dann den Prozessor neu 
startet (jetzt nur mal spekuliert).
Gast #5576754
Lesenswert?

Peter schrieb:
> Ja, aber was passiert wenn man es eben nicht vorsieht?

Im C++ Standard (N4659) heißt es in §7.10 (Arduino nutzt C++):

A prvalue of a floating-point type can be converted to a prvalue of an 
integer type. The conversion truncates; that is, the fractional part is 
discarded. The behavior is undefined if the truncated value cannot be 
represented in the destination type.

Das heißt, der Standard erlaubt es der Plattform 
(Compiler+Architektur+OS) einfach irgendetwas zu tun. Vielleicht kommt 0 
raus, vielleicht bleibt das Programm stehen, vielleicht formatiert es 
die Festplatte, vielleicht hängt das Ergebnis von der Mondphase ab, 
vielleicht hängt es von den Compiler-Einstellungen (Optimierung!) und 
-Version ab. Man sollte sich also keinesfalls darauf verlassen und 
vorher den Bereich prüfen.

Nutzt man den AVR-GCC mit avr-libc und avr-libm, was bei den 
AVR-Arduinos wohl der Fall ist, wird die Konvertierung mit der 
__fixsfsi-Funktion gemacht:
http://svn.savannah.gnu.org/viewvc/avr-libc/trunk/avr-libc/libm/fplib/fixsfsi.S?view=markup
Dort heißt es:

Return: The integral part of A. If A is too big (i.e. A is less then 
-0x0.ffffffp+31 or A is great then +0x0.ffffffp+31), this realization 
returns the LONG_MIN value (i.e. 0x80000000). If A is not a number, also 
LONG_MIN is returned.

Das ist aber eben spezifisch für diese Plattform und diese Version, 
darauf sollte man sich nicht verlassen. Ein allgemeines "Runtime Error" 
Konzept gibt es bei C und C++ nicht.
Beitrag #5577111 wurde von einem Moderator gelöscht.
Beitrag #5577140 wurde von einem Moderator gelöscht.
Beitrag #5577148 wurde von einem Moderator gelöscht.
Beitrag #5577149 wurde von einem Moderator gelöscht.
Beitrag #5577186 wurde von einem Moderator gelöscht.
Beitrag #5577247 wurde von einem Moderator gelöscht.
Beitrag #5577249 wurde von einem Moderator gelöscht.
Gast #5577318
Lesenswert?

Mach es über eine einfache Zuweisung. Vorher macht es dennoch Sinn, zu 
prüfen, ob das Ergebnis in deine Ganzzahl passt. Wenn zu groß, dann 
schreibe meinetwegen den Maximalwert rein, wenn zu klein, eine null oder 
mache was auch immer in deinem Fall Zweckmäßig ist. Das Verhalten kannst 
du aber auch einfach ausprobieren unter deinen Bedingungen und für dich 
entscheiden. Die zu wandelnde Variable einfach vorher mal mit 
verschiedenen Werten vorbelegen und dir die Resultate ansehen. Auch das 
Rundungsverhalten lässt sich damit ermitteln.
Gast #5577341
Lesenswert?

Patrick schrieb:
> Das Verhalten kannst du aber auch einfach ausprobieren unter deinen
> Bedingungen und für dich entscheiden

Nein. Da hier undefined behaviour eintreten kann, ist durch Ausprobieren 
ermitteltes Verhalten nicht verlässlich. Das kann bei der nächsten 
Compiler Version schon abweichen.

Patrick schrieb:
> Auch das Rundungsverhalten lässt sich damit ermitteln.

Unnötig, da wie gesagt immer die Nachkommastellen einfach gelöscht 
werden, d.h. es wird immer Richtung  0 auf ganze Zahlen gerundet.
Gast #5577353
Lesenswert?

Roth schrieb:
> Nur mal so gefragt: Wie kann ich einen Typecast von float nach unsigned
> int vornehmen?
>
> einfach so?
>
1
unsigned int Intvariable;
2
> float Floatvariable;
3
> Intvariable = Floatvariable;
>
> Eine rundung erfolgt dann vermutlich nach den üblichen Standards.
>
> Was aber, wenn Floatvariable zu groß ist? Gibts dann einen
> Runtime-Error?
>
> Ähm...wie äußert sich ein Runtime-Error auf dem Arduino eigentlich?
>
>
> ***
>
> Und noch eine Zusatzfrage: Bit-Schieben, z.B. '<<' geht mit float nicht,
> oder?

Einfache Frage. A: nein. Der int wert ist dann einfach falsch.
B: kann man mit Murks machen, bringt aber nur Nonsense. Das Ergebnis ist 
sicher nicht das, was du erwartest.

Grüsse,
René
Beitrag #5577361 wurde von einem Moderator gelöscht.
Beitrag #5577363 wurde von einem Moderator gelöscht.
Beitrag #5577384 wurde von einem Moderator gelöscht.
Beitrag #5577497 wurde von einem Moderator gelöscht.
Beitrag #5577499 wurde von einem Moderator gelöscht.
Gast #5577504
Lesenswert?

Roth schrieb im Beitrag #5577499:
> Was passiert denn nun konkret, wenn in einer MCU ohne Fehlerbehandlung
> ein unerlaubter Zustand auftritt, der weder vom Parser noch vom Compiler
> erkannt worden ist?

Der Parser ist Teil des Compilers... Was dann passiert hängt von tausend 
Dingen ab, insbesondere der Art des Fehlers, dem Prozessor, dem 
Compiler, der C(++) Standard Library. Es gibt keine zentrale 
Fehlerbehandlung (wie z.B. in Java). Einer der Gründe für die Effizienz 
von C(++) ist, dass an vielen Stellen keine Prüfung auf Fehler statt 
findet. Man ist als Programmierer selbst verantwortlich, es richtig zu 
machen. Tut man es nicht, passiert in vielen Fällen irgendetwas 
unvorhersehbares. Der einfachste Fall ist hier noch, dass der Controller 
abstürzt / stehen bleibt.
Beitrag #5577523 wurde von einem Moderator gelöscht.
Gast #5577530
Lesenswert?

René H. schrieb:
> Das ist eigentlich die Regel.

Naja... Speicher Zugriffs Fehler bewirken gerne auch mal, dass sich 
Variablen unerwartet ändern, Werte falsch abgelegt werden, irgendein 
Speicher Bereich als Code ausgeführt wird, usw. Es können auch einfach 
nur unerwartete Werte berechnet werden. Ein sauberer Absturz ist da der 
beste Fall, weil man dessen Stelle mit dem Debugger schnell findet...
#5577566
Lesenswert?

Roth schrieb im Beitrag #5577499:
> Was passiert denn nun konkret,
> wenn in einer MCU ohne Fehlerbehandlung ein unerlaubter Zustand
> auftritt, der weder vom Parser noch vom Compiler erkannt worden ist?

Du gehst von falschen Annahmen aus und stellst darum deine Frage falsch.

Wenn der Parser den Code nicht versteht, führt die MCU keinen Code aus, 
weil es kein Programm gibt. Ob der Compiler einen unerlaubten Zustand 
erkennt oder nicht, spielt ebenfalls keine Rolle. Es ist zudem egal, ob 
eine Fehlerbehandlung stattfindet, nachdem ein unerlaubter Zustand 
festgestellt wurde oder nicht.

C und C++ definieren vollumfänglich, was passiert, wenn ein unerlaubter 
Zustand auftritt: Nämlich "undefined behaviour" oder 
"implementation-defined behaviour". Konkret heißt das, dass dein 
Programm schon vor dem Start ungültig war und es ab sofort weder 
Zusicherungen irgendwelcher Art mehr gibt noch jemals gab. Ein 
Fachbegriff dazu sind "nasal demons".

Wenn du es noch konkreter wissen willst, dann musst du deinen Prozessor 
(bzw. dessen Datenblatt), deinen Compiler und dessen verwendete 
Bibliotheken in genau deiner verwendeten Version im Detail studieren: 
Dafür gibt es keinen Standard.

So, jetzt hast du mir ein paar fachliche Buchstaben aus dem Hinterteil 
gezogen. Ab sofort ignoriere ich dich dann.
Beitrag #5577569 wurde von einem Moderator gelöscht.
Gast #5577583
Lesenswert?

Dr. Sommer schrieb:
> René H. schrieb:
>> Das ist eigentlich die Regel.
>
> Naja... Speicher Zugriffs Fehler bewirken gerne auch mal, dass sich
> Variablen unerwartet ändern, Werte falsch abgelegt werden, irgendein
> Speicher Bereich als Code ausgeführt wird, usw. Es können auch einfach
> nur unerwartete Werte berechnet werden. Ein sauberer Absturz ist da der
> beste Fall, weil man dessen Stelle mit dem Debugger schnell findet...

Das ist so. Dass ist allerdings ein generelles C/C++ Problem. C++11 
versucht das zwar deutlich zu entschärfen, indem Pointer nicht mehr 
nötig sind, aber such mal ein Speicherproblem in Templates. Macht keinen 
Spass und kann dauern. Hatte ich schon divers bei Stl als auch boost.

Grüsse,
René
Beitrag #5577643 wurde von einem Moderator gelöscht.
Beitrag #5577655 wurde von einem Moderator gelöscht.
#5577750
Lesenswert?

Roth schrieb im Beitrag #5577499:
> Was passiert denn nun konkret,
> wenn in einer MCU ohne Fehlerbehandlung ein unerlaubter Zustand
> auftritt, der weder vom Parser noch vom Compiler erkannt worden ist? Ja,
> sowas gibt es.

Nein, sowas gibt es eben bei einfachen MCs nicht und das wurde auch 
schon mehrfach gesagt.
Du schreibst Code, der Compiler übersetzt ihn und die CPU führt ihn aus, 
basta. Erlaubt ist absolut jeder Maschinencode. Wenn Du Unsinn 
hinschreibst, führt die CPU eben Unsinn aus.

Du kannst natürlich ein OS installieren, z.B. UNIX, wenn Deine CPU 
genügend Ressourcen hat. Das OS kann dann einige Fehler, die Du in 
Deinem Programm gemacht hast, abfangen und Fehlermeldungen ausgeben.

In der Regel laufen Anwendungen auf einem MC aber direkt ohne jedwedes 
OS und ohne protected Mode. Willst Du irgendwelche Überwachungen, must 
Du sie auch selber hinschreiben. Z.B. um festzustellen, ob ein Code 
hängt, weil Du einen Fehler gemacht hast, kannst Du einen 
Watchdoginterrupt aufsetzen.
Beitrag #5577949 wurde von einem Moderator gelöscht.
Beitrag #5578041 wurde von einem Moderator gelöscht.
Beitrag #5578072 wurde von einem Moderator gelöscht.
Beitrag #5578076 wurde von einem Moderator gelöscht.
Beitrag #5578081 wurde von einem Moderator gelöscht.
Beitrag #5578082 wurde von einem Moderator gelöscht.
Beitrag #5578127 wurde von einem Moderator gelöscht.
Beitrag #5578151 wurde von einem Moderator gelöscht.
Beitrag #5578164 wurde von einem Moderator gelöscht.
Beitrag #5578186 wurde von einem Moderator gelöscht.
Beitrag #5578193 wurde von einem Moderator gelöscht.
Beitrag #5578200 wurde von einem Moderator gelöscht.
Beitrag #5578202 wurde von einem Moderator gelöscht.
Beitrag #5578222 wurde von einem Moderator gelöscht.
Dieser Beitrag ist gesperrt und kann nicht beantwortet werden.