Page 1 of 2

[SOLVED] Trying to make AbsInt()

Posted: Sun Sep 26, 2021 11:25 am
by Mijikai
I cant get my AbsInt() macro to work :?
Can someone pls point out my mistake :)

Code:

Code: Select all

EnableExplicit

Global dummy.i

Macro AbsInt(_val_)
  CompilerIf #PB_Compiler_Processor = #PB_Processor_x86
    !cmp dword[v_#_val_],0x0
    !jae @f
    !neg dword[v_#_val_]
    !@@:
  CompilerElse
    !cmp qword[v_#_val_],0x0
    !jae @f
    !neg qword[v_#_val_]
    !@@:
  CompilerEndIf
EndMacro

dummy = -42
AbsInt(dummy)

Debug dummy

End

Re: Trying to make AbsInt()

Posted: Sun Sep 26, 2021 1:25 pm
by BarryG
Is this no good for some reason?

Code: Select all

dummy.i = -42
dummy = Abs(dummy)
Debug dummy ; 42

Re: Trying to make AbsInt()

Posted: Sun Sep 26, 2021 2:19 pm
by Mijikai
BarryG wrote: Sun Sep 26, 2021 1:25 pm Is this no good for some reason?
...
That function is for floats and doubles.
It is not made for ints.

Re: Trying to make AbsInt()

Posted: Sun Sep 26, 2021 4:17 pm
by STARGÅTE
Such macro in combination with ASM would not work like you expected.
The name "v_var" is only right if var is a global variable. If it is in a procedure it would named like p.v_var etc.

I would recommend to use a normal procedure, which is fast enough:

Code: Select all

Procedure.i AbsInt(Var.i)
	If Var < 0
		ProcedureReturn -Var
	Else
		ProcedureReturn Var
	EndIf
EndProcedure

Debug AbsInt(-43)
Edit: corrected

Re: Trying to make AbsInt()

Posted: Sun Sep 26, 2021 4:48 pm
by Mijikai
STARGÅTE wrote: Sun Sep 26, 2021 4:17 pm Such macro in combination with ASM would work like you expected.
...
Thanks for the reply.

Now im even more confused, did the macro work for you?
It fails on the !cmp line for me and i cant figure out why.
Result is still -42

Re: Trying to make AbsInt()

Posted: Sun Sep 26, 2021 4:52 pm
by STARGÅTE
Mijikai wrote: Sun Sep 26, 2021 4:48 pm
STARGÅTE wrote: Sun Sep 26, 2021 4:17 pm Such macro in combination with ASM would work like you expected.
...
Thanks for the reply.

Now im even more confused, did the macro work for you?
It fails on the !cmp line for me and i cant figure out why.
Result is still -42
You have to compare with signed-values (JGE) instead of unsigned values (JAE):

Re: Trying to make AbsInt()

Posted: Sun Sep 26, 2021 4:56 pm
by Mijikai
Omg :shock: thank you :oops:

Re: [SOLVED] Trying to make AbsInt()

Posted: Sun Sep 26, 2021 5:06 pm
by Kiffi
Cheers!
Image
(SCNR)

Re: [SOLVED] Trying to make AbsInt()

Posted: Sun Sep 26, 2021 6:12 pm
by Mijikai
:mrgreen:
Sometimes u just 404

Re: Trying to make AbsInt()

Posted: Sun Sep 26, 2021 9:53 pm
by BarryG
Mijikai wrote: Sun Sep 26, 2021 2:19 pmThat function is for floats and doubles.
It is not made for ints.
But I just did it with an integer? My dummy variable was not of double or float type.

Re: [SOLVED] Trying to make AbsInt()

Posted: Sun Sep 26, 2021 10:23 pm
by STARGÅTE
BarryG wrote: Sun Sep 26, 2021 9:53 pm
Mijikai wrote: Sun Sep 26, 2021 2:19 pmThat function is for floats and doubles.
It is not made for ints.
But I just did it with an integer? My dummy variable was not of double or float type.
Interesting. Also the large Quads are handled correctly. But it wasn't always like that. And is dosn't work in the new c-backend

Code: Select all

Define Quad.q   = -9000000000000001234
Define Double.d = -9000000000000001234

Debug Quad
Debug Double
Quad   = Abs(Quad)
Double = Abs(Double)
Debug Quad
Debug Double
Asm-backend:
-9000000000000001234
-9000000000000001000.0
9000000000000001234 ; Abs used quads instead of double
9000000000000001000.0
C-backend:
-9000000000000001234
-9000000000000001000.0
9000000000000001024 ; << last digits are wrong.
9000000000000001000.0

Re: [SOLVED] Trying to make AbsInt()

Posted: Sun Sep 26, 2021 11:04 pm
by idle
This should work out better than a conditional jmp

Code: Select all

Macro mabsint(var) 
  EnableASM
  mov rdx, var
  mov rax, rdx 
  neg rax
  CMOVl rax,rdx
  mov var,rax
  DisableASM 
EndMacro   

Procedure absint(a.i)  
  !mov rdx,[p.v_a]
  !mov rax, rdx 
  !neg rax
  !CMOVl rax,rdx
  ProcedureReturn 
EndProcedure 

a=-42 
mabsint(a)
Debug a 
Debug absint(-42)  

Re: [SOLVED] Trying to make AbsInt()

Posted: Mon Sep 27, 2021 7:39 pm
by davido
@idle,
Thank you for sharing.

Re: [SOLVED] Trying to make AbsInt()

Posted: Wed Sep 29, 2021 9:32 pm
by Mijikai
Nice examples thanks for sharing everyone.
Im surprised that the simple function Stargate posted is so fast.

Here is another variant:

Code: Select all

Macro AbsInt(_val_)
  (1 - (Bool(_val_ < 0) << 1)) * _val_
EndMacro

There is also the msvcrt way (from the forum somewhere):

Code: Select all

EnableExplicit

Import "msvcrt.lib"
  CompilerIf #PB_Compiler_Processor = #PB_Processor_x64
    AbsInt.i(Value.i) As "_abs64"
  CompilerElse
    AbsInt.i(Value.i) As "_labs"
  CompilerEndIf
EndImport

Debug  AbsInt(-42)

End

Re: [SOLVED] Trying to make AbsInt()

Posted: Wed Oct 13, 2021 7:29 pm
by Michael Vogel
Interesing thread! Actually I've a lot of assembler routines for dealing with integers (iMin, iMax, iLimit, uMin, uMax, iAbs, iSign,...), strings (StringLen, StringFind, StringCrypt,...), doing faster image processing (ColorMix, ColorScale, MergePixel, MergeLine,...) and many other things.

The (only) reason for me using assembler code is s p e e d . So it will be interesting how to migrate all these functions to PB V6, I am not sure if the C-backend will be fast enough to get rid of all assembler routines.