Seite 1 von 3

Signumfunktion (nur 16 Zeichen)

Verfasst: 01.11.2006 14:02
von AND51
Hallo!

Neulich war mir in der Schule langweilig, da kritzelte ich auf meinen Block herum und irgendwann stellte ich mir die Aufgabe, die Signumfunktion in PB zu lösen :D

Code: Alles auswählen

Macro sgn(x)
(-(~~x<0)+(x>0))
EndMacro

Debug sgn(-5)
Debug sgn(0)
Debug sgn(7)
der Inhalt des Makros, auf das es ankommt, hat 16 Zeichen, nicht dass jemand die restlichen Zeichen mitzählt. Wenn jetzt ener kommt, und meint, er schafft das mit 14 Zeichen in einer Procedure, dann hatte ich die Idee vor ihm. procedures sind aber langsamer als makros und hier nicht angebracht.
Die Procedure hätte den Vorteil, dass die äußeren Klammern wegfallen, denn die Muss ich beim Makro haben, damit es sicherer ist, wenn ich das makro in komplexere ausdrücke einbaue.

Hier meine erste Version, die ich dann Schrittweise zusammengeschrumpft habe:

Code: Alles auswählen

; Version 1:
-(x < 0 And 1)+(x > 0 And 1)

; Version 2:
(-(Not Not x < 0)+(Not Not x > 0))
Noch eine kurze Erklärung zur Signumfunktion: Die mathematische Funktion "Signum" gibt immer nur 3 Werte zurück. Ergibt -1, wenn die eingesetzte zahl kleiner als null ist. Ergibt 0, wenn die zah gleich null ist. Ergibt 1, wenn die zahl größer als null ist.

Ach ja: Kann mir jemand ~ nochmal erklären? Ich kann mir nur an Karls Erklärung erinnern: "~ ist ein Not auf Bit-ebene"... Häää? Hier funktioniert es jedenfalls auch so... :lol:

Verfasst: 01.11.2006 14:10
von Kaeru Gaman
das bitwise not findest du auch in der help.

allerdings ist meiner meinung nach ein NotNot einfach überflüssig.

weiterhin ist es mit neu, dass Boole'sche Ausdrücke neuerdings auch ungecastet funktionieren.

Code: Alles auswählen

-(0 Or (X<0))+(0 Or (X>0))
wäre schon das minimum.
auch in einem macro müsstest du nen bool-cast reinmachen.
dass ein einziges ~~ das erledigt, wär mal ne ganz neue feature.

PS:
das Not Not mag diese funktion ausüben, so wie auch das And 1
aber ~ ist nunmal bitwise und nicht boolean.

Verfasst: 01.11.2006 15:09
von AND51
Ich glaube, so ungefähr habe ich es verstanden, was ~ ist.

Karl hat ~ in zusammenhang mit einer While-Schleife und Eof() benutzt:

Code: Alles auswählen

While ~Eof(0)
Das weiß ich noch genau. Dann ist sein Werk also auch "unsicher"?

Dein code:

Code: Alles auswählen

-(0 Or (X<0))+(0 Or (X>0))
-------^            ^
--------------------|
Diese Klammern und die jeweils direkt nachfolgenden, schließenden Klammern brauchst du nicht! statt dessen musst du um den ganzen Term eine Klammer setzen (weil das ja ein Makro ist).

Verfasst: 01.11.2006 15:27
von Kaeru Gaman

Code: Alles auswählen

While ~Eof(0)
geht, weil Eof() eben #NULL zurückgibt, solange das dateiende nicht erreicht ist.
~0 ist -1, und somit <>0 und damit in dem while so checkbar.

aber wenn man einen Logischen Operator braucht, um einen boolcast durchzuführen,
ist es nicht zwangsweise so, dass es mit einem bitoperator funktioniert.
es kann sein, dass es zufälliger weise funktioniert,
aber da das nicht auf zwingende logik basiert, würde ich die finger davon lassen.

> um den ganzen Term eine Klammer setzen (weil das ja ein Makro ist).
das ist korrekt, sonst ist es nicht vernünftig einzubaun in rechnungen.

> Diese Klammern und die jeweils direkt nachfolgenden, schließenden Klammern brauchst du nicht!
doch. genau die braucht man. weil man das ergebnis des vergleichs (X<0) boolcasten möchte.
der vergleichsoperator hat eine geringere priorität als der logische verknüpfer.
die klammer wegzulassen ergibt also dasselbe wie (0 Or X) < 0
und das ist eigentlich nicht das, was wir haben wollen.

Verfasst: 01.11.2006 15:30
von AND51
Kaeru Gaman hat geschrieben:> Diese Klammern und die jeweils direkt nachfolgenden, schließenden Klammern brauchst du nicht!
doch. genau die braucht man. weil man das ergebnis des vergleichs (X<0) boolcasten möchte.
der vergleichsoperator hat eine geringere priorität als der logische verknüpfer.
die klammer wegzulassen ergibt also dasselbe wie (0 Or X) < 0
und das ist eigentlich nicht das, was wir haben wollen.
Dann mach es doch so:

Code: Alles auswählen

(-(X<0 Or 0)+(X>0 Or 0))
Habe außerdem um den ganzen Termeine Klammer gesetzt.



Achja: Wenn du mir jetzt noch sagen könntest, was "boolcasten" ist, dann kann ich auch ruhig schlafen... :wink:

Verfasst: 01.11.2006 15:34
von Tafkadasom2k5
Ein Boolcast ist, wenn ich das noch richtig weiß, das boolsche Ergebnis eines Wertes.

So ist der Wert "20" in einer normalen if-Abfrage ("if 20") immer 1. Geboolcasted ist es also "TRUE".

Die Boolean-Antwort einer eigentlich nicht-Boolschen Gleichung...

Gr33tz
Tafkadasom2k5

Verfasst: 01.11.2006 15:45
von Kaeru Gaman
> Dann mach es doch so:
damit setzt du voraus, dass vergleichsoperator und logischer operator gleiche priorität haben.
ich weiß nicht, ob es so ist, es erscheint mir unwahrscheinlich.

zum sauberen logischen proggen gehören nun mal klammern. Basta.

> was "boolcasten" ist
als Typecast bezeichnet man den vorgang, innerhalb eines ausdrucks
einer variablen einen anderen Typ zuzuweisen, als sie eigentlich hat.

in PB war das vor ein paar versionen noch nötig,
z.b. eine komplexere rechnung mit einer float anzufangen,
nicht mit einer integer, wenn eine float herauskommen sollte.
sonst wurde der beginn des terms in integer gerechnet, und es konnten fehler auftreten.
scheint aber in 4.0 behoben zu sein.

"boolcasten" bedeutet dementsprechen, einem ausdruck einen True/False-Typ zuzuweisen.
diesen Typ gibt es offiziell in PB nicht, aber die verknüpfung mit einem logischen operator
ist der (bisher) einzige weg, Boole'sche Ausdrücke wie (X>0) in PB auszuwerten.

-------------------------------------------------------------------
...yo sakra... gibts das doch inzwischen?

muss ich mal ausgiebig testen, vielleicht ist dieses konstrukt ein sonderfall.
aber

Code: Alles auswählen

Macro sig(X)
(-(X<0)+(X>0))
EndMacro
scheint zu funktionieren *kopfkratz*

Verfasst: 01.11.2006 16:45
von AND51
Danke für die Erklärung zu Boolcasting.


Kaeru Gaman hat geschrieben:damit setzt du voraus, dass vergleichsoperator und logischer operator gleiche priorität haben.
Stimmt doch gar nicht! Ich weiß bereits, dass logische Operatoren eine geringere Priorität als Vergleichsoperatoren haben, ist ja auch sinnvoll so.
PB Hilfe hat geschrieben:

Code: Alles auswählen

Priorität von Operatoren

  Prioritäts-Level |     Operatoren
  -----------------+---------------------
         7         |        ~
         6         |    <<, >>, %, !
         5         |       |, &
         4         |       *, /
         3         |       +, -
         2         | >, >=, <, <=, =, <>
         1         |  And, Or, Not, XOr

Verfasst: 01.11.2006 17:09
von Little John
2AND51:
Toll, dass Du das entdeckt hast.
Wenn Du dein Makro aufräumst, reichen auch 13 Zeichen .... Kommst Du drauf? :)

Gruß, Little John

Verfasst: 01.11.2006 18:46
von remi_meier
@KG:
Die "Or 0" bzw. "And 1" Methode ist genau so unsicher wie das da oben, man
muss es einfach in allen Lagen testen, bis man "sicher" sein kann, dass es
funktioniert.

Ihr müsst einfach warten, bis Fred das endlich einbaut :|