Nur mal so gefragt: Wie kann ich einen Typecast von float nach unsigned
int vornehmen?
einfach so?
1
unsignedintIntvariable;
2
floatFloatvariable;
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?
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ß?
;)
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)
Roth schrieb:> Nur mal so gefragt: Wie kann ich einen Typecast von float nach unsigned> int vornehmen?>> einfach so?>
1
unsignedintIntvariable;
2
>floatFloatvariable;
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
@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?
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
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.
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.
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)
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).
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.
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.
Intvariable = (unsigned int)Floatvariable;
für Floatvariable<0 sollte 0 das Ergebniss sein,
für Floatvariable>65535 musst du probieren oder vorher testen.
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.
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.
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.
Roth schrieb:> Nur mal so gefragt: Wie kann ich einen Typecast von float nach unsigned> int vornehmen?>> einfach so?>
1
unsignedintIntvariable;
2
>floatFloatvariable;
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é
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.
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é
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...
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.
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é
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.
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.