Page 2 of 5
					
				Re: Absolute Val for Integers?
				Posted: Mon Jan 21, 2019 2:25 pm
				by Olliv
				@Little John
No problem. Your research allows me to discover several details, like most of researching which are shared.
Finally this subject becomes a small mine of datas, just from a simple missing feature...
			 
			
					
				Re: Absolute Val for Integers?
				Posted: Mon Jan 21, 2019 5:10 pm
				by mk-soft
				Simple way 
 
 
Code: Select all
Import ""
  Abs64(quad.q) As "_abs64"
  Abs32(long.l) As "labs"
EndImport
var1.i = -1
Debug Abs64(var1)
var2.l = -10
Debug Abs32(var2)
 
			
					
				Re: Absolute Val for Integers?
				Posted: Mon Jan 21, 2019 5:14 pm
				by wilbert
				mk-soft wrote:Simple way 
 
 
Code: Select all
Import ""
  Abs64(quad.q) As "_abs64"
  Abs32(long.l) As "labs"
EndImport
var1.i = -1
Debug Abs64(var1)
var2.l = -10
Debug Abs32(var2)
 
For MacOS and Linux you would need 
llabs instead of _abs64 .
 
			
					
				Re: Absolute Val for Integers?
				Posted: Mon Jan 21, 2019 5:28 pm
				by mk-soft
				Is ImportC right?
Code: Select all
CompilerSelect #PB_Compiler_OS
  CompilerCase #PB_OS_Windows
    Import ""
      Abs64(quad.q) As "_abs64"
      Abs32(long.l) As "labs"
    EndImport
  CompilerCase #PB_OS_Linux
    ImportC ""
      Abs64(quad.q) As "llabs"
      Abs32(long.l) As "labs"
    EndImport
  CompilerCase #PB_OS_MacOS
    ImportC ""
      Abs64(quad.q) As "_llabs"
      Abs32(long.l) As "_labs"
    EndImport
CompilerEndSelect
var1.i = -1
Debug Abs64(var1)
var2.l = -10
Debug Abs32(var2)
 
			
					
				Re: Absolute Val for Integers?
				Posted: Mon Jan 21, 2019 6:05 pm
				by wilbert
				mk-soft wrote:Is ImportC right?
For MacOS and Linux it is working fine for PB x64.  
 
 
Unfortunately I can't test for PB x86.
 
			
					
				Re: Absolute Val for Integers?
				Posted: Tue Jan 22, 2019 8:25 am
				by Lord
				May I ask a question?
Why does Helle's Abs(64) return wrong a result:
Code: Select all
;Windows x64
If OpenLibrary(0, "msvcrt.dll")
  Prototype.q Abs64(V1.q)
  Abs64.Abs64 = GetFunction(0, "_abs64")
  CloseLibrary(0)
 Else
  ;Error
EndIf
1105645676897669811
1105645676897669711
mk-soft's Abs64() gives the correct result:
Code: Select all
Import ""
  Abs64(quad.q) As "_abs64"
EndImport
var1.i = 1105645676897669811
Debug var1
Debug Abs64(var1)
1105645676897669811
1105645676897669811
At least on my machine.
 
			
					
				Re: Absolute Val for Integers?
				Posted: Tue Jan 22, 2019 9:06 am
				by djes
				Helle wrote:
y1.q = 100
z1.q = 110564567689766987
x1.q = y1 - z1
Debug Abs64(x1)
 
 
			
					
				Re: Absolute Val for Integers?
				Posted: Tue Jan 22, 2019 9:53 am
				by wilbert
				As a macro ...  
 
 
Code: Select all
Macro _Abs(n)
  ((n)*(Bool((n)>0)*2-1))
EndMacro
Debug _Abs(100 - 110564567689766987)
Debug _Abs(-2.75)
 
			
					
				Re: Absolute Val for Integers?
				Posted: Tue Jan 22, 2019 10:30 am
				by NicTheQuick
				But remember it will not work for the lowest number. In fact you can turn a seemingly positive value into a negative one. Normally there should be an exception but unforrtunality there is no such option for Purebasic.
Code: Select all
var1.i = 9223372036854775808
Debug Abs64(var1)
 
			
					
				Re: Absolute Val for Integers?
				Posted: Tue Jan 22, 2019 2:42 pm
				by Josh
				infratec wrote:Josh wrote:And why doesn't do Pb this by itself?  Shouldn't be so complicated that Abs () automatically detects whether it is an integer or a float.
Does PB offer you the posibility to have one procedure parameter which can reperesent different types?
Even if you use a structure with Union, how can you decide if it is a float or an integer value?
It is not so easy as you think.
 
- You can't compare Pb functions with a user procedure. In some cases Pb functions do more, than you can do with procedures.
- You can't execute the function Abs() on a structure but only on an element of the structure. So it is clear what type it is.
 
			
					
				Re: Absolute Val for Integers?
				Posted: Tue Jan 22, 2019 4:44 pm
				by Lord
				That's strange:
Lord wrote:May I ask a question?
Why does Helle's Abs(64) return wrong a result:
Code: Select all
;Windows x64
If OpenLibrary(0, "msvcrt.dll")
  Prototype.q Abs64(V1.q)
  Abs64.Abs64 = GetFunction(0, "_abs64")
  CloseLibrary(0)
 Else
  ;Error
EndIf
1105645676897669811
1105645676897669711
mk-soft's Abs64() gives the correct result:
Code: Select all
Import ""
  Abs64(quad.q) As "_abs64"
EndImport
var1.i = 1105645676897669811
Debug var1
Debug Abs64(var1)
1105645676897669811
1105645676897669811
At least on my machine.
 
I did a Copy&Paste of both, codes and results from IDE and debugger output, to this forum.
Now I copied both snippets from forum back to my IDE and now I get from both codes the same results.  
 
 
Magic?
 
			
					
				Re: Absolute Val for Integers?
				Posted: Tue Jan 22, 2019 9:31 pm
				by idle
				just tried this out of curiosity 
Code: Select all
Macro IABS(v) ;in line with out branching 
   ((v) ! ((v)>>((SizeOf(integer)<<3)-1))) - ((v)>>((SizeOf(integer)<<3)-1))
EndMacro
a = -123 
a = IAbs(a) 
Debug a 
and with the courtesy of the peep hole optimizer  results in 
  MOV    r15,qword [v_a]
  MOV    r14,qword [v_a]
  SAR    r14,63
  XOR    r15,r14
  MOV    r14,qword [v_a]
  SAR    r14,63
  SUB    r15,r14
  MOV    qword [v_a],r15
 
			
					
				Re: Absolute Val for Integers?
				Posted: Wed Jan 23, 2019 12:39 am
				by Olliv
				This is clever (very), but it does not solve an exception problem.
First, branch prevents the CPU to process with a sign flag  random state as we can see above.
Second, branch must be used to manage an exception, and show us, we must give a procedure address to treat it.
Code: Select all
Procedure IntegerAbsoluteException()
    MessageRequester("Error", "Domain overflow")
EndProcedure
Procedure IntegerAbs(A.Q, *exceptionaddr)
    ! mov rbx, 0x8000000000000000 ; THE problem
    ! xor rax, rax
    ! add rax, [p.v_A]
    ! Jns positive
    ! cmp rax, rbx
    ! jz exception
    ! xor rax, 0xffffffffffffffff
    ! add rax, 1
    ! positive:
    ProcedureReturn
    ! exception:
    ! call qword [p.p_exceptionaddr]
EndProcedure
Debug IntegerAbsolute(-5, @IntegerAbsoluteException() )
Floats float, but integers do not float.
 
			
					
				Re: Absolute Val for Integers?
				Posted: Wed Jan 23, 2019 1:23 am
				by jack
				@idle
that's very compact code, just for fun I tried the following in the compiler explorer C++ 
https://godbolt.org
Code: Select all
long long int iabs(long long int v)
{
return (v<0) ? -v:v;
}
resulting asm, (rdi holds the argument)
Code: Select all
        mov     rdx, rdi
        mov     rax, rdi
        sar     rdx, 63
        xor     rax, rdx
        sub     rax, rdx
        ret
except for different registers, it's practically identical
 
			
					
				Re: Absolute Val for Integers?
				Posted: Wed Jan 23, 2019 1:34 am
				by idle
				jack wrote:@idle
that's very compact code, just for fun I tried the following in the compiler explorer C++ 
https://godbolt.org
Code: Select all
long long int iabs(long long int v)
{
return (v<0) ? -v:v;
}
resulting asm, (rdi holds the argument)
Code: Select all
        mov     rdx, rdi
        mov     rax, rdi
        sar     rdx, 63
        xor     rax, rdx
        sub     rax, rdx
        ret
 
I'm mystified how it transforms a ternary if into that, yes that's pretty much the optimal
pity cant do that as an inline macro though. 
Olliv raised an important point, there is a need to check for overflow $8000000000000000
though I'm not sure if it should raise and exception
@Olliv
could wrap the overflow to 0 so it can be tested ? 
you'd still have to check anyway if you were going to do a divide
Code: Select all
Macro IABS(v) ;in place no branching peep hole optimizer works 
   (((v) ! ((v)>>((SizeOf(integer)<<3)-1))) - ((v)>>((SizeOf(integer)<<3)-1))) & ($8000000000000000-1)
EndMacro
a = $8000000000000000;-1
b = IAbs(a) 
If b 
  Debug "valid abs " + b  
Else 
  Debug "invalid abs 0 or overflow"  
EndIf