Absolute Val for Integers?

Just starting out? Need help? Post your questions and find answers here.
User avatar
Olliv
Enthusiast
Enthusiast
Posts: 542
Joined: Tue Sep 22, 2009 10:41 pm

Re: Absolute Val for Integers?

Post 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...
User avatar
mk-soft
Always Here
Always Here
Posts: 6204
Joined: Fri May 12, 2006 6:51 pm
Location: Germany

Re: Absolute Val for Integers?

Post by mk-soft »

Simple way :wink:

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)
My Projects ThreadToGUI / OOP-BaseClass / EventDesigner V3
PB v3.30 / v5.75 - OS Mac Mini OSX 10.xx - VM Window Pro / Linux Ubuntu
Downloads on my Webspace / OneDrive
wilbert
PureBasic Expert
PureBasic Expert
Posts: 3942
Joined: Sun Aug 08, 2004 5:21 am
Location: Netherlands

Re: Absolute Val for Integers?

Post by wilbert »

mk-soft wrote:Simple way :wink:

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 .
Windows (x64)
Raspberry Pi OS (Arm64)
User avatar
mk-soft
Always Here
Always Here
Posts: 6204
Joined: Fri May 12, 2006 6:51 pm
Location: Germany

Re: Absolute Val for Integers?

Post 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)
My Projects ThreadToGUI / OOP-BaseClass / EventDesigner V3
PB v3.30 / v5.75 - OS Mac Mini OSX 10.xx - VM Window Pro / Linux Ubuntu
Downloads on my Webspace / OneDrive
wilbert
PureBasic Expert
PureBasic Expert
Posts: 3942
Joined: Sun Aug 08, 2004 5:21 am
Location: Netherlands

Re: Absolute Val for Integers?

Post 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.
Windows (x64)
Raspberry Pi OS (Arm64)
User avatar
Lord
Addict
Addict
Posts: 900
Joined: Tue May 26, 2009 2:11 pm

Re: Absolute Val for Integers?

Post 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.
Image
User avatar
djes
Addict
Addict
Posts: 1806
Joined: Sat Feb 19, 2005 2:46 pm
Location: Pas-de-Calais, France

Re: Absolute Val for Integers?

Post by djes »

Helle wrote: y1.q = 100
z1.q = 110564567689766987
x1.q = y1 - z1
Debug Abs64(x1)
:?:
wilbert
PureBasic Expert
PureBasic Expert
Posts: 3942
Joined: Sun Aug 08, 2004 5:21 am
Location: Netherlands

Re: Absolute Val for Integers?

Post 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)
Windows (x64)
Raspberry Pi OS (Arm64)
User avatar
NicTheQuick
Addict
Addict
Posts: 1504
Joined: Sun Jun 22, 2003 7:43 pm
Location: Germany, Saarbrücken
Contact:

Re: Absolute Val for Integers?

Post 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)
The english grammar is freeware, you can use it freely - But it's not Open Source, i.e. you can not change it or publish it in altered way.
User avatar
Josh
Addict
Addict
Posts: 1183
Joined: Sat Feb 13, 2010 3:45 pm

Re: Absolute Val for Integers?

Post 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.
sorry for my bad english
User avatar
Lord
Addict
Addict
Posts: 900
Joined: Tue May 26, 2009 2:11 pm

Re: Absolute Val for Integers?

Post 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. :shock:
Magic?
Image
User avatar
idle
Always Here
Always Here
Posts: 5836
Joined: Fri Sep 21, 2007 5:52 am
Location: New Zealand

Re: Absolute Val for Integers?

Post 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
Windows 11, Manjaro, Raspberry Pi OS
Image
User avatar
Olliv
Enthusiast
Enthusiast
Posts: 542
Joined: Tue Sep 22, 2009 10:41 pm

Re: Absolute Val for Integers?

Post 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.
jack
Addict
Addict
Posts: 1358
Joined: Fri Apr 25, 2003 11:10 pm

Re: Absolute Val for Integers?

Post 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
User avatar
idle
Always Here
Always Here
Posts: 5836
Joined: Fri Sep 21, 2007 5:52 am
Location: New Zealand

Re: Absolute Val for Integers?

Post 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 

Windows 11, Manjaro, Raspberry Pi OS
Image
Post Reply