Forum: Compiler & IDEs Funktion liefert falsche werte


von karsten (Gast)


Lesenswert?

hallo,


die funktion:
1
//Zykluszeit = 0.01593752490238265997290620
2
//Tickspermeter = 96000
3
//ausgabe soll die schrittgeschwindigkeit eines steppers in µm/s sein
4
unsigned long Calc_speed(unsigned long Value, unsigned long Tickspermeter)
5
{
6
  //unsigned long result;
7
  return ( 1000000 / Zykluszeit / Tickspermeter * (1/Value));
8
  // result;
9
}
auf gerufen wird sie wie folgt
1
stepwartezeit = Calc_speed(meinSpeedlong, Tickspermeterlong);

wenn ich es mit dem wert 1000 (ist 1mm/sek) mache, geht es.
bei mehr oder weniger kommt nur mist raus. woran kann das liegen?

von DirkB (Gast)


Lesenswert?

(1/Value) ist für Value > 1 immer 0

Ich komme bei deinen Werten auf 0.6irgendwas und das ist als unsigned 
long auch 0.

von kask (Gast)


Lesenswert?

ja, schon.

aber das ist mitten in der berrechnung. da sollte das value als unsigned 
gesehen werden. die ausgabe "1/unsigned" aber nicht.

steht doch in klammern und der variabelen "Value" wird der wert nicht 
zugewiesen.

oder sehe ich das total falsch?

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

kask schrieb:
> aber das ist mitten in der berrechnung. da sollte das value als unsigned
> gesehen werden. die ausgabe "1/unsigned" aber nicht.

Das hat nichts mit "unsigned" zu tun, sondern damit, daß Du hier 
integer-Arithmetik betreibst.

Und für die ist 1/2 = 0.

von kask (Gast)


Lesenswert?

ok,
aber was muß ich machen damit es funktioniert und die funktion mir eine 
(unsigned) long ausgibt aber mit z.b. einer gleitkommazahl rechnet?

von Peter II (Gast)


Lesenswert?

kask schrieb:
> aber mit z.b. einer gleitkommazahl rechnet?

warum willst du mit gleitkommazahl rechen wenn du am ende long 
rausbekommen willst?

Wechen wert erwartest du denn?

von kask (Gast)


Lesenswert?

ich erwarte wenn ich folgendes eingebe z.b.:
value = 500 das ca. 1308 rauskommt,
value = 1000 das ca. 654 rauskommt,
value = 2000 das ca. 327 rauskommt.

so wie es jeder taschenrechner macht. mehr will ich nicht ;)

von Justus S. (jussa)


Lesenswert?

kask schrieb:
> ich erwarte wenn ich folgendes eingebe z.b.:
> value = 500 das ca. 1308 rauskommt,
> value = 1000 das ca. 654 rauskommt,
> value = 2000 das ca. 327 rauskommt.
>
> so wie es jeder taschenrechner macht. mehr will ich nicht ;)

komisch, mein Taschenrechner kommt auf 1.308, 0.654 und 0.327 und damit 
als long 1, 0 und 0

und hat es einen tieferen Sinn
1
 *(1/value)
 statt gleich
1
/value
zu schreiben?

von 4???? (Gast)


Lesenswert?

Dann Stimmen deine Werte aber nicht:

1000000 / Zykluszeit = 62745000
                       62745000 / 96000 = 653,6
                                          653,6 * (1/1000) = 0,653


Du musst Umstellen und Klammern:
1000000  Zykluszeit  Tickspermeter * (1/Value) =
1000000 / ( Zykluszeit  Tickspermeter  Value) =
1000000  Zykluszeit  (Tickspermeter * Value)


Wobei du 1000000 / Zykluszeit evtl. schon vorher ausrechnen kannst.
Denn deine Zykluszeit sieht sehr berechnet aus :-)

von Peter II (Gast)


Lesenswert?

kask schrieb:
> mehr will ich nicht

dann mach es dem compiler doch nicht so schwer


return 653594 / value;

(runden fehlt noch)

von kask (Gast)


Lesenswert?

ups, da is was faul.

richtiger wäre
1
return ( 1000000 / Zykluszeit / Tickspermeter * (1/(Value/1000)));

oder
1
return ( 1000000000 / Zykluszeit / Tickspermeter * (1/(Value)));

wobei es sicher besser wäre "1000000000 / Zykluszeit" vorher zu 
berrechnen. macht sinn ;)

und jepp, die zykluszeit is berrechnet bzw. gemessen.
100%ige genauigkeit ist nicht primär.

aber haste auch wieder recht. feste werte und gut ist. wenn sich die 
hardware ändert kann man auch neu compilieren ;)

von kask (Gast)


Lesenswert?

jepp runden fehlt noch..das ist das nächste thema..wie?
ich suche mir in sachen c nen kippar***. bei simpelen sachen.

so wie ich es erlesen habe macht er es automatisch wenn ich der ausgabe 
ganzzahl eine gleitkommazahl zuweise. (wie in bascom z.b.)

von 4???? (Gast)


Lesenswert?

Aber auch bei
1
return ( 1000000000 / Zykluszeit / Tickspermeter * (1/(Value)));

würde 0 rauskommen, da (1/value) als Ganzzahlwert berechnet wird, und 
das ist 0.
1
return ( 1000000000 / Zykluszeit / Tickspermeter / Value);
macht das was du brauschst.

Oder du hast ein Zykluszeit als #define. Dann rechnet der Compiler das 
schon vorher aus.

von kask (Gast)


Lesenswert?

ich brauche aber die "1/"..

weil sonst wir der ausgage wert immer größer bei größer werden der 
eingabe.
es muß aber kleiner werden bei größer werdender eingabe.

von kask (Gast)


Lesenswert?

okok, dank dir hast recht ich falsch gedacht ;)

von Johann (Gast)


Lesenswert?

kask schrieb:
> ich brauche aber die "1/"..

Schmarren.

von 4???? (Gast)


Lesenswert?

kask schrieb
> ich brauche aber die "1/"..

Dein Problem war nicht unbedingt die 1/ sondern die Klammern drum herum.

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.