Forum: Mikrocontroller und Digitale Elektronik Arduino: Typecast von float nach unsigned int


von Roth (Gast)


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?

: Gesperrt durch Moderator
von Blubb (Gast)


Lesenswert?

Wieso will man überhaupt auf nem Arduino, der keine FPU hat mit float 
werten arbeiten?

von Roth (Gast)


Lesenswert?

Blubb schrieb:
> Wieso will man überhaupt auf nem Arduino, der keine FPU hat mit float
> werten arbeiten?
Wieso muss jemand antworten, der keine Antwort weiß?
;)

von Einer K. (Gast)


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)

von Bastian W. (jackfrost)


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

von Roth (Gast)


Lesenswert?

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

von Bastian W. (jackfrost)


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

von Rolf M. (rmagnus)


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.

von Roth (Gast)


Lesenswert?

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

Ist die Frage zu schwer? Dann ziehe ich sie zurück.

von Michael R. (mr-action)


Lesenswert?

Es gibt keinen Runtime-Error...

von Dr. Sommer (Gast)


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.

von Luglio Zähsar (Gast)


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)

von Peter (Gast)


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

von ma.N. (Gast)


Lesenswert?

Peter schrieb:
> Könnte mir vorstellen
> das bei Arduino ein Watchdog aktiv ist, der dann den Prozessor neu
> startet (jetzt nur mal spekuliert).

Zu viel Spekulatius gegessen oder was?! Spekulier hier nicht rum sondern 
beleg deine Behauptungen.

von m.n. (Gast)


Lesenswert?

Roth schrieb:
> Und noch eine Zusatzfrage: Bit-Schieben, z.B. '<<' geht mit float nicht,
> oder?

Braucht man auch nicht. Einfach das Byte, das den Exponenten darstellt 
um 1 erhöhen. Das erspart dann die Multiplikation ;-)

Du solltest schreiben, was Du vor hast.

von dummschwaetzer (Gast)


Lesenswert?

Intvariable = (unsigned int)Floatvariable;
für Floatvariable<0 sollte 0 das Ergebniss sein,
für Floatvariable>65535 musst du probieren oder vorher testen.

von Dr. Sommer (Gast)


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.
von Patrick (Gast)


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.

von Dr. Sommer (Gast)


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.

von René H. (Gast)


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.
von Dr. Sommer (Gast)


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.
von René H. (Gast)


Lesenswert?

Dr. Sommer schrieb:
> er einfachste Fall ist hier noch, dass der Controller
> abstürzt / stehen bleibt.

Das ist eigentlich die Regel. Bleibt stehen oder Reset. In den wenigsten 
Fällen wird ein interrupt ausgelöst. Alles andere (Sonderfälle) will man 
nicht suchen :-).

Grüsse,
René

von Dr. Sommer (Gast)


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

von S. R. (svenska)


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.

: Bearbeitet durch User
Beitrag #5577569 wurde von einem Moderator gelöscht.
von René H. (Gast)


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.
von Peter D. (peda)


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.

von Nils P. (torus)


Lesenswert?

Roth schrieb:
> Und noch eine Zusatzfrage: Bit-Schieben, z.B. '<<' geht mit float nicht,
> oder?

Jein. Reines Bitschieben geht nicht. Es gibt aber ein mathematisches 
Äquivalent:

So entspricht:

  unsigned int x = a << b;

diesem hier:

  float x = ldexpf (a,b);

Beides wird mathematisch als

   x = a * 2^b;

gereichnet.

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.