Float als ProcedureReturn Wert

Anfängerfragen zum Programmieren mit PureBasic.
DerMeister
Beiträge: 28
Registriert: 30.12.2009 19:20

Float als ProcedureReturn Wert

Beitrag von DerMeister »

Hallo
Ich habe versucht eine Procedure zu schreiben, die den Sinuswert eines Winkels berechnet, ohne dass ich ihn vorher in Radiant umberechnen muss.

Code: Alles auswählen

Procedure Sinus(Zahl.f)
  Ergebnis.f = Sin(Zahl.f / 57.29577951)
  ProcedureReturn Ergebnis
EndProcedure  

Debug Sinus(45)
Jedoch wird der ausgegebene Wert immer auf oder abgerundet zu einem ganzzahligen Wert.
Wie kann ich es schaffen, dass ein Floatwert von der Funktion zurückgegeben wird?
Kaeru Gaman
Beiträge: 17389
Registriert: 10.11.2004 03:22

Re: Float als ProcedureReturn Wert

Beitrag von Kaeru Gaman »

ach Kollege, da muss man doch nun wirklich mal Bild sagen!

häng den gewünschten Typ des Rückgabewertes an die "Procedure" Deklaration:

Code: Alles auswählen

Procedure.f Sinus(Zahl.f)

... außerdem werd ichs nach "Anfänger" verschieben, wo's hingehört.
Der Narr denkt er sei ein weiser Mann.
Der Weise weiß, dass er ein Narr ist.
Benutzeravatar
Josh
Beiträge: 1028
Registriert: 04.08.2009 17:24

Re: Float als ProcedureReturn Wert

Beitrag von Josh »

DerMeister hat geschrieben:Hallo
es ist halt noch kein meister vom himmel gefallen :mrgreen:
Benutzeravatar
STARGÅTE
Kommando SG1
Beiträge: 7031
Registriert: 01.11.2005 13:34
Wohnort: Glienicke
Kontaktdaten:

Re: Float als ProcedureReturn Wert

Beitrag von STARGÅTE »

im übrigen ist es besser (und schneller)
wenn du nicht
Sin(Zahl.f / 57.29577951)
rechen lässt, sonden dir eine Konstante definierst:
#DegToRad = #PI/180
und dann in deiner Procedure multiplizierst:
Sin(Zahl.f * #DegToRad)

das mag n Kleinigkeit sein, aber viele kleinigkeiten wirken zusammen und beschleuinigen ein Programm später enorm :-)
PB 6.01 ― Win 10, 21H2 ― Ryzen 9 3900X, 32 GB ― NVIDIA GeForce RTX 3080 ― Vivaldi 6.0 ― www.unionbytes.de
Aktuelles Projekt: Lizard - Skriptsprache für symbolische Berechnungen und mehr
Kaeru Gaman
Beiträge: 17389
Registriert: 10.11.2004 03:22

Re: Float als ProcedureReturn Wert

Beitrag von Kaeru Gaman »

@STARGÅTE

deinen Einwand verstehe ich jetzt nicht - wo soll der qualitative Unterschied sein, ob du die Konstante literal oder tokenized hinschreibst?

wesentlich performancekritischer ist der Call, hier würde sich ein Macro statt der Procedure anbieten, falls es zeitkritisch ist.
Der Narr denkt er sei ein weiser Mann.
Der Weise weiß, dass er ein Narr ist.
Benutzeravatar
ts-soft
Beiträge: 22292
Registriert: 08.09.2004 00:57
Computerausstattung: Mainboard: MSI 970A-G43
CPU: AMD FX-6300 Six-Core Processor
GraKa: GeForce GTX 750 Ti, 2 GB
Memory: 16 GB DDR3-1600 - Dual Channel
Wohnort: Berlin

Re: Float als ProcedureReturn Wert

Beitrag von ts-soft »

Hab zwar keine Ahnung von sinus usw., aber wenn ich erst teile und dann multipliziere erhöhen sich die Rundungsfehler.
Somit sollte die erste Variante genauer sein, jedenfalls nach meinem mathematischem Verständnis.

Gruß
Thomas
Benutzeravatar
STARGÅTE
Kommando SG1
Beiträge: 7031
Registriert: 01.11.2005 13:34
Wohnort: Glienicke
Kontaktdaten:

Re: Float als ProcedureReturn Wert

Beitrag von STARGÅTE »

es geht um das Multiplizieren, statt Dividieren !

das man dann n Konstante statt der Zahl nimmt ist reine Formsache ... umd man weiß später noch was 0.01745329252 bedeutet ...

@TS

Das macht er ja auch, er Teilt erst 180/#Pi "per Hand" und nutzt diesen Wert, der damit auch fehler behaftet ist, auch noch mal zum dividieren seines Winkels...

Es werden also so oder so mehrere Schritte gemacht und PI in PB ist sowieso nur gerundet (inzwischen zum glück als Double)
PB 6.01 ― Win 10, 21H2 ― Ryzen 9 3900X, 32 GB ― NVIDIA GeForce RTX 3080 ― Vivaldi 6.0 ― www.unionbytes.de
Aktuelles Projekt: Lizard - Skriptsprache für symbolische Berechnungen und mehr
Kaeru Gaman
Beiträge: 17389
Registriert: 10.11.2004 03:22

Re: Float als ProcedureReturn Wert

Beitrag von Kaeru Gaman »

es geht um das Multiplizieren, statt Dividieren !
interessant... worauf basierst du diese Aussage?

trotzdem kann man ganz easy hinschreiben

Code: Alles auswählen

Ergebnis.f = Sin(Zahl.f * #PI / 180)
weil PB die Konstanten und Literale zur Compilezeit zusammenzieht.

... außerdem wäre es wohl erwägenswert, hier beiderseitig mit Double zu arbeiten.

... letzteres fällt beim Macro flach:

Code: Alles auswählen

Macro Sinus( _expr_ )
  Sin( ( _expr_ ) * #PI / 180 )
EndMacro
Der Narr denkt er sei ein weiser Mann.
Der Weise weiß, dass er ein Narr ist.
Benutzeravatar
ts-soft
Beiträge: 22292
Registriert: 08.09.2004 00:57
Computerausstattung: Mainboard: MSI 970A-G43
CPU: AMD FX-6300 Six-Core Processor
GraKa: GeForce GTX 750 Ti, 2 GB
Memory: 16 GB DDR3-1600 - Dual Channel
Wohnort: Berlin

Re: Float als ProcedureReturn Wert

Beitrag von ts-soft »

Weiß jetzt nicht in welcher Reihenfolge PB es macht, habe also extra Klammern gesetzt:

Code: Alles auswählen

Ergebnis.f = Sin((Zahl.f * #PI) / 180)
Somit wird die Multiplikation vor der Division ausgeführt und die Genauigkeit erhöht sich gegenüber
dem vorher Teilen. Double könnten auch hilfreich sein :wink:
(Gottseidank brauch ich sowas so gut wie nie)
Kaeru Gaman
Beiträge: 17389
Registriert: 10.11.2004 03:22

Re: Float als ProcedureReturn Wert

Beitrag von Kaeru Gaman »

ts-soft hat geschrieben:Somit wird die Multiplikation vor der Division ausgeführt und die Genauigkeit erhöht sich gegenüber
dem vorher Teilen.
damit erschaffst du aber einen performance einbruch, weil das Programm zur Laufzeit beide Operationen durchführen muss.
ohne die Klammern wird PB zur Compilezeit die beiden Konstanten #PI und 180 verrechnen, und als eine einzige Konstante in die EXE übernehmen.


wenn es sich hier nicht um zwei Konstanten handeln würde sondern um Variablen, wäre dein Einwand natürlich berechtigt.
allerdings muss man dann wieder aufpassen, dass man keinen Overflow bekommt,
bei manchen Zahlenbereichen ist es besser, erst zu teilen dann zu multiplizieren, damit man nicht oben anstößt.
Der Narr denkt er sei ein weiser Mann.
Der Weise weiß, dass er ein Narr ist.
Antworten