Not() mal geht's mal kennt er es nicht...

Anfängerfragen zum Programmieren mit PureBasic.
Little John

Beitrag von Little John »

Hallo Kaeru, da hatten sich unsere Posts überschnitten ...
Kaeru Gaman hat geschrieben:

Code: Alles auswählen

F = (1=0)      ; Hier _kann_ der zuzuweisende Ausdruck in Klammern stehen. 
dieses hier ist komplett falsch!
PB unterstützt Boole'sche Ausdrücke in rechnungen und zuweisungen nicht,
bzw. nicht unbedingt mit den gewünschten ergebnissen.

Code: Alles auswählen

a = 4
b = 6
t = ( a = b )
If t = #False
  Debug "ungleich"
Else
  Debug "gleich"
EndIf
Debug "t = "+Str(t)
Du hast recht. Ich hatte das nicht näher geprüft.
Alle anderen mir bekannten prozeduralen Programmiersprachen verhalten sich so wie ich es auch für PB angenommen hatte. Dass PB sich hier anders verhält kann ich nur als skurril bezeichnen. Aber man sollte es wissen, danke für den Hinweis.

Gruß, Little John
Kaeru Gaman
Beiträge: 17389
Registriert: 10.11.2004 03:22

Beitrag von Kaeru Gaman »

an dem punkt war jeder hier mal, der genug erfahrung mit anderen programmiersprachen mitgebracht hat.

es gibt ein inoffizielles workaround:
wenn man den Boole'sche Ausdruck mit einem logischen Operator verknüpft,
dann ist das ergebnis wieder #True oder #False, und kann in berechnungen einfließen.

Code: Alles auswählen

For a = 0 To 9
  b = 9 - a
  c = a * ((a > b) Or #False) + b * ((a < b) Or #False)
  Debug Str(a)+", "+Str(b)+" => "+Str(c)
Next
funktionalität für zukünftige versionen ist nicht garantiert.
ich weiß nicht einmal, ob es mit der brandneuen 4.1 noch wie erwartet funktioniert.
Der Narr denkt er sei ein weiser Mann.
Der Weise weiß, dass er ein Narr ist.
Little John

Beitrag von Little John »

Kaeru Gaman hat geschrieben:an dem punkt war jeder hier mal, der genug erfahrung mit anderen programmiersprachen mitgebracht hat.
Das ist beruhigend. :)
Kaeru Gaman hat geschrieben:es gibt ein inoffizielles workaround:
wenn man den Boole'sche Ausdruck mit einem logischen Operator verknüpft, dann ist das ergebnis wieder #True oder #False,
Auf Dein vorheriges Beispiel angewendet sieht das z.B. so aus:

Code: Alles auswählen

a = 4
b = 6

t = (a = b)
Debug t                   ; zeigt leider 6
t = (Not (Not (a = b)))
Debug t                   ; zeigt wie erwartet 0 (= Wert für #False)
Wenn ich im passenden Moment daran denke, kann ich damit leben.
Kaeru Gaman hat geschrieben:und kann in berechnungen einfließen.

Code: Alles auswählen

For a = 0 To 9
  b = 9 - a
  c = a * ((a > b) Or #False) + b * ((a < b) Or #False)
  Debug Str(a)+", "+Str(b)+" => "+Str(c)
Next
Berechnungen möchte ich mit Booleschen Werten ganz bestimmt nicht anstellen (siehe diese Nachricht). Aber Zuweisungen wie oben werde ich sicher dann und wann brauchen. Danke.

Gruß, Little John
Kaeru Gaman
Beiträge: 17389
Registriert: 10.11.2004 03:22

Beitrag von Kaeru Gaman »

> Auf Dein vorheriges Beispiel angewendet sieht das z.B. so aus
oder so:

Code: Alles auswählen

a = 4
b = 6
t = ( (a = b) Or #False )
Debug t
mindestens ein "Bool-Cast" auf den Ausdruck muss halt vorkommen.


> Berechnungen möchte ich mit Booleschen Werten ganz bestimmt nicht anstellen

Geschmackssache. wenn Boole'sche Ausdrücke zuverlässig funktionieren,
und die zurückgegebenen werte für #True und #False eindeutig sind,
kann man damit sehr praktische dinge machen, z.b.

Code: Alles auswählen

x = x + Step * ( x < 799 ) - x * (x >= 799 )
dieses beispiel funktioniert in PB halt nur, wenn man bei beiden ausdrücken den Boolcast hinzufügt.
Zuletzt geändert von Kaeru Gaman am 01.06.2007 12:52, insgesamt 1-mal geändert.
Der Narr denkt er sei ein weiser Mann.
Der Weise weiß, dass er ein Narr ist.
Benutzeravatar
Kurzer
Beiträge: 1617
Registriert: 25.04.2006 17:29
Wohnort: Nähe Hamburg

Beitrag von Kurzer »

Wow, danke für Eure Grundsatzdiskussion. Selbst bei solchen Kleinigkeiten kann man ja noch ne Menge falsch machen.

Ich denke, mit

Code: Alles auswählen

x = (Not x) 
...liege ich erstmal am kompatibelsten richtig, wenn x = boolsch ist.

Dat Forum ist :allright:
"Never run a changing system!" | "Unterhalten sich zwei Alleinunterhalter... Paradox, oder?"
PB 6.12 x64, OS: Win 11 24H2 x64, Desktopscaling: 150%, CPU: I7 12700 H, RAM: 32 GB, GPU: Intel(R) Iris(R) Xe Graphics | NVIDIA GeForce RTX 3070
Useralter in 2025: 57 Jahre.
Little John

Beitrag von Little John »

Kaeru Gaman hat geschrieben:> Auf Dein vorheriges Beispiel angewendet sieht das z.B. so aus
oder so:

Code: Alles auswählen

a = 4
b = 6
t = ( (a = b) Or #False )
Debug t
mindestens ein "Bool-Cast" auf den Ausdruck muss halt vorkommen.
Danke, das werd' ich mir 'mal als Standard-Lösung merken. Ist eleganter als mein Not (Not ...).
Kaeru Gaman hat geschrieben:> Berechnungen möchte ich mit Booleschen Werten ganz bestimmt nicht anstellen

Geschmackssache. wenn Boole'sche Ausdrücke zuverlässig funktionieren,
und die zurückgegebenen werte für #True und #False eindeutig sind,
kann man damit sehr praktische dinge machen, z.b.

Code: Alles auswählen

x = x + Step * ( x < 799 ) - x * (x >= 799 )
dieses beispiel funktioniert in PB halt nur, wenn man bei beiden ausdrücken den Boolcast hinzufügt.
Bei ca. 99% der Leute, die sich mit Mathematik auskennen, rollen sich bei sowas die Fußnägel hoch. :D

Außerdem ist das auch noch gefährlich, denn welche (Zahlen-)Werte eine Programmiersprache verwendet um #False und #True zu repräsentieren ist willkürlich. Selbst verschiedene Basic-Dialecte verwenden unterschiedliche Werte, so benutzt z.B. PowerBasic für #True nicht 1, sondern -1. (Dass PowerBasic ebenso wie PureBasic gerne mit PB abgekürzt wird, verkleinert nicht gerade das Fehlerpotential.) Ein Code wie

Code: Alles auswählen

x = x + Step * ( x < 799 ) - x * (x >= 799 )
würde also in PowerBasic anders funktionieren als in PureBasic.
Zusätzlich zu den Nachteilen die ich bereits beschrieben habe handelt man sich hier ohne jede Not völlig unnötigerweise eine zusätzliche potentielle Fehlerquelle ein.

Gruß, Little John
Kaeru Gaman
Beiträge: 17389
Registriert: 10.11.2004 03:22

Beitrag von Kaeru Gaman »

> so benutzt z.B. PowerBasic für #True nicht 1, sondern -1.
war aufm C64 genauso, wo ich mit ausdrücken rechnen gelernt hab.
ich hatte auch schon drum diskutiert, dass es in PureB genauso gemacht wird.
(weil -1 = alle bits gesetzt, 0 = alle bits gelöscht, ~0 = -1, etc.)


> ohne jede Not
und eben das ist der punkt.
PureBasic gehört nicht zu den sprachen, wo es einen Vorteil bringen würde,
es ist also höchstens "irgendwie chique", aber ohne jeden Nutzen.

wie man hier sehen kann, ist die klassische If-Variante nicht nur viel besser lesbar,
sondern auch noch annähernd doppelt so schnell:
(remember: Debugger ausschalten!)

Code: Alles auswählen

x = 0
stp = 7
timer1 = ElapsedMilliseconds()
  For n=0 To 999999999
    x = x + stp * (( x < 799 ) Or #False ) - 800 * ((x >= 799 ) Or #False )
  Next
timer1 = ElapsedMilliseconds() - timer1

x = 0
timer2 = ElapsedMilliseconds()
  For n=0 To 999999999
    x + stp
    If x > 799
      x - 800
    EndIf
  Next
timer2 = ElapsedMilliseconds() - timer2

out$ = "Boolesh Algorithm: "+Str(timer1) + #CRLF$
out$ + "Algorithm using If: "+Str(timer2)

MessageRequester("Test",Out$)
mal ganz abgesehen davon, dass die ergebnisse nicht genau übereinstimmen.
es ist also einfach widersinnig, in PB so ein Konstrukt zu benutzen.


die einzige anwendung bleibt also die zuweisung ein eine variable,
die für eine spätere auswertung den Bool-Wert rückspeichern soll.
Der Narr denkt er sei ein weiser Mann.
Der Weise weiß, dass er ein Narr ist.
Antworten