Immer noch kein Abs() für Integer

Fragen und Bugreports zur PureBasic 4.0-Beta.
Kaeru Gaman
Beiträge: 17389
Registriert: 10.11.2004 03:22

Immer noch kein Abs() für Integer

Beitrag von Kaeru Gaman »

warum gibt es immer noch kein Abs() für integer?

klar, das ist nicht schwierig selbst zu implementieren, aber das ärgerliche ist,
dass das son rumgedaddel ist, das MSB zu löschen, wenn man nicht weiß,
ob der übergebene wert nun Word, Long oder Quad ist.

ich bin grad dabei, ein paar macros zu schreiben, und ich bräuchte mal da ein Abs().
eigentlich hatte ich nicht vor, mehrere macros zu schachteln bzw. das macro unnötig zu verkomplizieren.

ich finds einfach ärgerlich. :roll:


PS:
und ich stelle grad fest, dass ich nich einfach mal so ein macro schreiben kann, was das MSB löscht, da eben an Abs() auch ausdrücke übergeben werden können, und die kann man nicht als Argumente für SizeOf() verwenden. also doch ne boole'sche lösung.
Der Narr denkt er sei ein weiser Mann.
Der Weise weiß, dass er ein Narr ist.
Benutzeravatar
mk-soft
Beiträge: 3855
Registriert: 24.11.2004 13:12
Wohnort: Germany

Beitrag von mk-soft »

MSB löschen?,
Da kommt ein falsches Ergebnis herraus. Alle Bits Invertieren und dann plus Eins oder nur Mal minus Eins

FF :wink:

P.S.

Code: Alles auswählen

Procedure.w AbsW(value.w)
  If value < 0
    ProcedureReturn ~value + 1
  EndIf
EndProcedure

Procedure.l AbsL(value.l)
  If value < 0
    ProcedureReturn ~value + 1
  EndIf
EndProcedure

Debug AbsW(2)
Debug AbsW(-2)
Debug AbsW(-32767)

Debug AbsL(2)
Debug AbsL(-2)
Debug AbsL(-123456789)
Alles ist möglich, fragt sich nur wie...
Projekte ThreadToGUI / EventDesigner V3 / OOP-BaseClass-Modul
Downloads auf MyWebspace / OneDrive
Kaeru Gaman
Beiträge: 17389
Registriert: 10.11.2004 03:22

Beitrag von Kaeru Gaman »

äh.. ja, mit If alles kein thema, ich brauch aber ein Macro.

klar könnte ich den funktionsaufruf ins macro einbaun, darauf würde ich aber gerne verzichten, wenn möglich.
(wenn möglich, es wird aber wohl ziemlich komplex)

gibt es keine einfache operation, die man auf positive und negative werte anwenden kann, um das korrekte ergebnis rauszubekommen?

re: MSB löschen
stimmt ja, is ja ganz was anderes.. denkfehler. uralter denkfehler. eigentlich hatte ich das schon seit jahrzehnten begriffen, es war mir nur entglitten.
Der Narr denkt er sei ein weiser Mann.
Der Weise weiß, dass er ein Narr ist.
Benutzeravatar
helpy
Beiträge: 636
Registriert: 29.08.2004 13:29

Beitrag von helpy »

Hier noch eine kleines Abs-Macro, das nicht ganz so rechenintensiv ist:

Code: Alles auswählen

Macro AbsX(x)
	( ((x>>(SizeOf(x)*8-1)) | 1 ) * x)
EndMacro
!!! Funktioniert aber nur für Variablen vom Typ .b, .w, .l und .q ... funktioniert nicht für Ausdrücke und Konstanten!

Angetestet mit folgendem Code:

Code: Alles auswählen

Macro test(x,wert)
	x = wert
	Debug "Size = " + Str(SizeOf(x)) + " :: Wert = " + Str(x) + " :: Abs = " + Str(AbsX(x))
EndMacro

b.b
w.w
l.l
q.q

test(b,10)
test(w,1000)
test(l,100000)
test(q,10000000)

test(b,0)
test(w,0)
test(l,0)
test(q,0)

test(b,-10)
test(w,-1000)
test(l,-100000)
test(q,-10000000)

test(b,-1)
test(w,-1)
test(l,-1)
test(q,-1)
cu, helpy
Kaeru Gaman
Beiträge: 17389
Registriert: 10.11.2004 03:22

Beitrag von Kaeru Gaman »

hups, diesen thread hatte ich ja ganz vergessen... :roll:

nuja, das macro müsste auf jeden fall ausdrücke verarbeiten können...

also, hier ist mein macro, das auch für ausdrücke funktioniert:

Code: Alles auswählen

Macro AbsEx(Expression) 
  ((Expression) * (-1 * ((Expression) < 0 Or 0)) + ((Expression) >= 0 Or 0) * (Expression)) 
EndMacro 
ist aber sehr rechenintensiv, da der ausdruck 4x vorkommt und auch 4x ausgewertet wird.
die Proc mit If ist wesentlich schneller.

ein macro kann halt nicht so etwas wie einen rückgabewert haben, außer wie in diesem fall, das komplette macro ist ein ausdruck der das gewünschte ergebnis evaluiert.

ich hab jetzt halt doch ne Proc genommen *duck*
da ichs in ein anderes Macro einbauen wollte, konnte ich an der stelle dann doch eine Proc benutzen...
http://www.purebasic.fr/german/viewtopi ... 9743#99743
Der Narr denkt er sei ein weiser Mann.
Der Weise weiß, dass er ein Narr ist.
Benutzeravatar
helpy
Beiträge: 636
Registriert: 29.08.2004 13:29

Beitrag von helpy »

Du kannst die Formel etwas vereinfachen:

Code: Alles auswählen

Macro AbsEx(Expression)
  ( ( ((Expression) >= 0 Or 0) - ((Expression) < 0 Or 0) ) * (Expression) )
EndMacro
Kaeru Gaman
Beiträge: 17389
Registriert: 10.11.2004 03:22

Beitrag von Kaeru Gaman »

ah.. cool

stimmt, meine "denkschlappe"

und jetzt fällt mir die noch kürzere lösung ein:

Code: Alles auswählen

Macro AbsEx(Expression) 
  ( ( ((Expression) >= 0 Or 0) *2 - 1  ) * (Expression) ) 
EndMacro
Der Narr denkt er sei ein weiser Mann.
Der Weise weiß, dass er ein Narr ist.
Gesperrt