Signumfunktion (nur 16 Zeichen)

Hier könnt Ihr gute, von Euch geschriebene Codes posten. Sie müssen auf jeden Fall funktionieren und sollten möglichst effizient, elegant und beispielhaft oder einfach nur cool sein.
Benutzeravatar
AND51
Beiträge: 5220
Registriert: 01.10.2005 13:15

Signumfunktion (nur 16 Zeichen)

Beitrag 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:
PB 4.30

Code: Alles auswählen

Macro Happy
 ;-)
EndMacro

Happy End
Kaeru Gaman
Beiträge: 17389
Registriert: 10.11.2004 03:22

Beitrag 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.
Der Narr denkt er sei ein weiser Mann.
Der Weise weiß, dass er ein Narr ist.
Benutzeravatar
AND51
Beiträge: 5220
Registriert: 01.10.2005 13:15

Beitrag 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).
PB 4.30

Code: Alles auswählen

Macro Happy
 ;-)
EndMacro

Happy End
Kaeru Gaman
Beiträge: 17389
Registriert: 10.11.2004 03:22

Beitrag 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.
Der Narr denkt er sei ein weiser Mann.
Der Weise weiß, dass er ein Narr ist.
Benutzeravatar
AND51
Beiträge: 5220
Registriert: 01.10.2005 13:15

Beitrag 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:
PB 4.30

Code: Alles auswählen

Macro Happy
 ;-)
EndMacro

Happy End
Benutzeravatar
Tafkadasom2k5
Beiträge: 1578
Registriert: 13.08.2005 14:31
Kontaktdaten:

Beitrag 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
OpenNetworkConnection() hat geschrieben:Versucht eine Verbindung mit dem angegebenen Server aufzubauen. 'ServerName$' kann eine IP-Adresse oder ein voller Name sein (z.B.: "127.0.0.1" oder "ftp.home.net").
php-freak hat geschrieben:Ich hab die IP von google auch ned rausgefunden!
Kaeru Gaman
Beiträge: 17389
Registriert: 10.11.2004 03:22

Beitrag 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*
Der Narr denkt er sei ein weiser Mann.
Der Weise weiß, dass er ein Narr ist.
Benutzeravatar
AND51
Beiträge: 5220
Registriert: 01.10.2005 13:15

Beitrag 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
PB 4.30

Code: Alles auswählen

Macro Happy
 ;-)
EndMacro

Happy End
Little John

Beitrag 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
Benutzeravatar
remi_meier
Beiträge: 1078
Registriert: 29.08.2004 20:11
Wohnort: Schweiz

Beitrag 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 :|
Antworten