Der Faktor 100 ist nur um Fließkommazahlen "wegzubekommen".
Nun kommt es vor, dass natürlich die neue Geschwindigkeit langsamer als
die alte ist, d.h. es wird verzögert. Die Beschleunigung ist daher
negativ. Ich bekomme aber auf meinem LCD immer eine positive Ausgabe. Es
liegt an den unsigned Variablen ulGeschwindigkeitalt und
ulGeschwindigkeitneu. Aber wie caste ich das auf ein signed, sodass die
Berechnung noch stimmt?
Kann mir jemand helfen?
Danke.
Daniel schrieb:> Nun kommt es vor, dass natürlich die neue Geschwindigkeit langsamer als> die alte ist, d.h. es wird verzögert. Die Beschleunigung ist daher> negativ.
Deshalb hast du auch das Problem, ein uint32_t fasst nunmal keine
negativen Zahlen. Entweder du kannst auf int32_t wechseln (welcher
Wertebereich wird verwendet), oder du musst auf int64_t umsatteln (wird
der vom compiler/der libc unterstützt)?
Ja, das ist richtig, das weiß ich soweit auch, dass es keine negative
Zahlen fasst.
Das uint32_t wird aber nicht "voll ausgeschöpft", d.h. es ist noch Platz
in den 32-bit, Wertebereich < 32-bit/2. Weshalb ich es in der Berechnung
einfach casten wollte auf ein int32.
Daniel schrieb:> Das uint32_t wird aber nicht "voll ausgeschöpft", d.h. es ist noch Platz> in den 32-bit, Wertebereich < 32-bit/2.
Warum nimmst Du dann nicht, wie von "Programmierer" vorgeschlagen,
gleich int32 für Deine Geschwindigkeitsvariablen?
Weil ich zuvor mit diesen Variablen eine unsigned Rechnung benötige, da
ich diese aus einem Zeitstempel hole und die Differenz dieser
Zeitstempel berechne. Da hier ein Überlauf auftreten kann (da der Timer
ja durchläuft), benötige ich zuvor eine unsigned Rechnung. Erst bei der
Beschleunigung können dann negative Werte auftreten.
Klar, ich könnte das zuvor in ein int32_t übertragen und mit diesen dann
weiter rechnen. Ich dachte aber man könnte es einfach casten...
Allerdings kann es zu Überläufen kommen: Bei der Multiplikation und auch
bei der Differenzbildung, weil die Differenz zweier n-Bit Variablen von
-2^n bis 2^n reichen kann; die entsprechende signed-Variable aber nur
Werte von -2^{n-1} bis 2^{n-1}-1 halten kann.
Klaus Wachtler schrieb:> ssBeschleunigung =
(((int32_t)ulGeschwindigkeitalt-ulGeschwindigkeitneu)*100)/ulGeschwindig keitneu);
Ein einziger Cast reicht nicht. Bei einer Operation, in der signed- und
unsigned-Operanden vorkommen, wird erstmal der signed-Operand nach
unsigned konvertiert (also in diesem Fall dein Cast wieder rückgängig
gemacht) und dann die Rechnung in unsigned durchgeführt.
der dritte ist geschenkt...
Einfacher wäre der Tip mit einem Blick in ein passendes Buch; wieso
sollen wir immer nachsehen, wenn einer zu faul ist (ok, man könnte es
sich auch merken, aber wenn ich es wirklich brauche schaue ich nach -
wieso können die Frager das nicht, um ihr Problem zu lösen?).
- Weil der Frager ein Anfänger ist und (noch) kein C-Buch besitzt.
- Weil der Frager dachte, dass Foren dazu da sind und es auch anerkennt,
wenn andere Leute in ihrer Freizeit helfen
- Weil auch Dritte davon noch lernen können ;-)
Danke.
Naja, aber wenn jemand jetzt für den Rest seines Lebens jedes Problem
dieser Qualität von anderen lösen lässt, ist das etwas ineffizient.
Wenn ich wissen will, was irgendein Wort auf Englisch heißt, frage ich
nicht in einem Forum und beschäftige damit Leute, sondern schlage halt
da nach, wo es steht. Analog alle anderen Trivialitäten.
Sinn eines Forums ist doch eher, wirkliche Probleme zu lösen, die nicht
eben mal durch Nachschlagen zu erledigen sind. Eher weniger, allen
Leuten aus dem K&R oder dem Stroustrup vorzulesen, weil sie keine Lust
haben, selbst zu lesen.
Und eben genau solche Rechenregeln stehen in einem besseren C-Buch und
sie sind auch leicht im Internet zu finden.
Insofern habe ich kein schlechtes Gewissen, darauf zu verweisen und
nicht als ehrenamtlichen Arschnachtrager nachzuschlagen und ihm
vorzulesen.
Die Leute, die hier regelmäßig kompetent Auskunft geben, haben ihr
Handwerk gelernt, indem sie sich drum gekümmert haben, und nicht indem
sie für jeden Tastendruck sich von jemandem bedienen haben lassen.
Das geht jetzt nicht gegen die ursprüngliche Frage; ich will da
niemanden groß anmeckern. Aber du hattest die Frage nach dem Sinn eines
Forums erwähnt. Da bestehen durchaus unterschiedliche Ansichten...
M.M. nach ist die Frage durchaus berechtigt, wenn du das Problem damit
hast. Berechtigt ist aber auch der Hinweis, daß man sowas in einem Buch
findet.
Wenn du mit einem solchen Hinweis nicht weiterkommst, wirst du beim
Programmieren nicht alt werden.
"Nun kommt es vor, dass natürlich die neue Geschwindigkeit langsamer als
die alte ist, d.h. es wird verzögert. Die Beschleunigung ist daher
negativ."
Dann sollte da wohl eher:
stehen, oder? Allerdings verstehe ich nicht, wie du so Beschleunigung
berechnest. Wenn du Geschwindigkeit durch Geschwindigkeit teilst, dann
bekommst du eine dimensionslose Zahl. Du brauchst aber m/s^2, musst
daher (Die Differenz von) Geschwindigkeit durch Zeit teilen.
Nun wie auch immer:
Du musst nicht casten wenn du nicht willst. Sollte die Gefahr bestehen,
dass das casten einen Überlauf produziert, weil ua,un >INT_MAX sein
können, dann rechne einfach:
1
if(ua>un)
2
s=(int16_t)((100*(ua-un))/u2);/* So wie in deinem Code */
3
else
4
s=-(int16_t)((100*(un-ua))/u2);/* einfach umdrehen und später negativ machen */
Das dürfte besser sein, als mit int64_t anzufangen.