int128

User contributed sources that have become inactive, deprecated, or generally unusable. But ... we don't really want to throw them away either.
srvaldez
Posts: 3373
Joined: Sep 25, 2005 21:54

int128

Post by srvaldez »

I compiled this library using gcc 64-bit, so it's 64-bit only because gcc 32-bit does not support int128.
you can use either the dll or static lib, I think that all the bugs/coding mistakes are fixed.
lib128
Last edited by srvaldez on Jun 13, 2017 23:11, edited 2 times in total.
MrSwiss
Posts: 3910
Joined: Jun 02, 2013 9:27
Location: Switzerland

Re: int128

Post by MrSwiss »

@srvaldez,

the signed type 128 seems to be unsigned (it's definition is identical to unsigned).
I'd code it as follows:

Code: Select all

Type int128_t
    As ULongInt l
    As LongInt  h
End Type
srvaldez
Posts: 3373
Joined: Sep 25, 2005 21:54

Re: int128

Post by srvaldez »

hello MrSwiss
you are right about the order of the elements but I think they should be unsigned, you only need to use a different conversion routine for int128_t, btw I forgot/overlooked u128shl.
of course you will also need a string to int128_t routine.
MrSwiss
Posts: 3910
Joined: Jun 02, 2013 9:27
Location: Switzerland

Re: int128

Post by MrSwiss »

hello srvaldez,

while that is true for Type uint128_t, it is not correct, for "signed" 128bit Type. My opinion.
The "l" element must be ULongInt, but the "h" element must be "signed" LongInt ...
St_W
Posts: 1619
Joined: Feb 11, 2009 14:24
Location: Austria
Contact:

Re: int128

Post by St_W »

Have you thought about publishing the source code for this? (for the DLL)

I think the data type in the FB UDT is rather irrelevant as it is only used for data storage, no matter whether you use 16 (U)Byte, 8 (U)Short, 4 (U)Long or 2 (U)LongInt the result is always a block of 16 continuous bytes in memory (assuming byte alignment), and that is the only thing that counts. Using only parts of the number does not represent the normal usecase but is rather a very special use case that may require byte/short/long or longInt depending on the task. You may think about general purpose CPU registers in the x86_64 architecture and will see that there's no distinction between signed/unsigned. Rather multiple different functions are used to handle byte sequences/registers either as signed or unsigned. Furthermore multiple (overlapping) partitions of the byte-sequence/register exist (which could e.g. be represented by a union), here a sample for a 64-bit number:

Code: Select all

0x1122334455667788
  ================ rax (64 bits)
          ======== eax (32 bits)
              ====  ax (16 bits)
              ==    ah (8 bits)
                ==  al (8 bits)
It would be nice if 128-bit datatypes could be integrated in the compiler, but that would probably require a lot of work.
srvaldez
Posts: 3373
Joined: Sep 25, 2005 21:54

Re: int128

Post by srvaldez »

St_W wrote:Have you thought about publishing the source code for this? (for the DLL)
yes, as soon I it get to work right, right now the unsigned operations seem to work but not so the signed and changing from ulongint to longint makes no difference.
srvaldez
Posts: 3373
Joined: Sep 25, 2005 21:54

Re: int128

Post by srvaldez »

the problem was that I was handling the signed conversion wrong, should be ok now.
srvaldez
Posts: 3373
Joined: Sep 25, 2005 21:54

Re: int128

Post by srvaldez »

all finished :-)
srvaldez
Posts: 3373
Joined: Sep 25, 2005 21:54

Re: int128

Post by srvaldez »

I just updated lib128, I think (I hope) that the conversion functions are bug free now.
int128.bi

Code: Select all

#inclib "128"

type int128_t
	as ulongint l, h
    Declare Constructor ( )
    Declare Constructor ( ByVal As Long )
    Declare Constructor ( ByVal As Longint )
    Declare Constructor ( ByRef As String )
    Declare Constructor ( ByRef As int128_t )
    Declare Destructor ( )
    Declare Operator Let ( ByRef As int128_t )
    Declare Operator Let ( ByVal As Long)
    Declare Operator Let ( ByVal As Longint)
    Declare Operator Let ( ByRef As String )
    Declare Operator Cast ( ) As Long
    Declare Operator Cast ( ) As Longint
    Declare Operator Cast ( ) As String
    ' For Next Implicit step = +1
    Declare Operator For ( )
    Declare Operator Step( )
    Declare Operator Next( Byref end_cond As int128_t ) As Integer
    ' For Next Exlicit step
    Declare Operator For ( Byref stp As int128_t )
    Declare Operator Step( Byref stp As int128_t )
    Declare Operator Next( Byref end_cond As int128_t, Byref step_var As int128_t ) As Integer
end type

type uint128_t
	as ulongint l, h
    Declare Constructor ( )
    Declare Constructor ( ByVal As uLong )
    Declare Constructor ( ByVal As uLongint )
    Declare Constructor ( ByRef As String )
    Declare Constructor ( ByRef As uint128_t )
    Declare Destructor ( )
    Declare Operator Let ( ByRef As uint128_t )
    Declare Operator Let ( ByVal As uLong)
    Declare Operator Let ( ByVal As uLongint)
    Declare Operator Let ( ByRef As String )
    Declare Operator Cast ( ) As uLong
    Declare Operator Cast ( ) As uLongint
    Declare Operator Cast ( ) As String
    ' For Next Implicit step = +1
    Declare Operator For ( )
    Declare Operator Step( )
    Declare Operator Next( Byref end_cond As uint128_t ) As Integer
    ' For Next Exlicit step
    Declare Operator For ( Byref stp As uint128_t )
    Declare Operator Step( Byref stp As uint128_t )
    Declare Operator Next( Byref end_cond As uint128_t, Byref step_var As uint128_t ) As Integer
end type

dim shared As int128_t izero, ione
izero.l=0 : izero.h=0
ione.l=1 : ione.h=0

dim shared As uint128_t uzero, uone
uzero.l=0 : uzero.h=0
uone.l=1 : uone.h=0

extern "C"

Declare sub i128add  (byval x as int128_t  ptr, byval y as int128_t  ptr , byval r as int128_t  ptr)
Declare sub i128addl (byval x as int128_t  ptr, byval y as long          , byval r as int128_t  ptr)
Declare sub li128add (byval x as long         , byval y as int128_t  ptr , byval r as int128_t  ptr)
Declare sub i128addll(byval x as int128_t  ptr, byval y as longint       , byval r as int128_t  ptr)
Declare sub lli128add(byval x as longint      , byval y as int128_t  ptr , byval r as int128_t  ptr)
Declare sub i128div  (byval x as int128_t  ptr, byval y as int128_t  ptr , byval r as int128_t  ptr)
Declare sub i128divl (byval x as int128_t  ptr, byval y as long          , byval r as int128_t  ptr)
Declare sub i128divll(byval x as int128_t  ptr, byval y as longint       , byval r as int128_t  ptr)
Declare sub i128mod  (byval x as int128_t  ptr, byval y as long          , byval r as long      ptr)
Declare sub i128modll(byval x as int128_t  ptr, byval y as longint       , byval r as longint   ptr)
Declare sub i128mul  (byval x as int128_t  ptr, byval y as int128_t  ptr , byval r as int128_t  ptr)
Declare sub i128mull (byval x as int128_t  ptr, byval y as long          , byval r as int128_t  ptr)
Declare sub i128mulll(byval x as int128_t  ptr, byval y as longint       , byval r as int128_t  ptr)
Declare sub i128sub  (byval x as int128_t  ptr, byval y as int128_t  ptr , byval r as int128_t  ptr)
Declare sub i128subl (byval x as int128_t  ptr, byval y as long          , byval r as int128_t  ptr)
Declare sub i128subll(byval x as int128_t  ptr, byval y as longint       , byval r as int128_t  ptr)
Declare sub u128add  (byval x as uint128_t ptr, byval y as uint128_t ptr , byval r as uint128_t ptr)
Declare sub u128addl (byval x as uint128_t ptr, byval y as ulong         , byval r as uint128_t ptr)
Declare sub u128addll(byval x as uint128_t ptr, byval y as ulongint      , byval r as uint128_t ptr)
Declare sub u128and  (byval x as uint128_t ptr, byval y as uint128_t ptr , byval r as uint128_t ptr)
Declare sub u128div  (byval x as uint128_t ptr, byval y as uint128_t ptr , byval r as uint128_t ptr)
Declare sub u128divl (byval x as uint128_t ptr, byval y as ulong         , byval r as uint128_t ptr)
Declare sub u128divll(byval x as uint128_t ptr, byval y as ulongint      , byval r as uint128_t ptr)
Declare sub u128mod  (byval x as uint128_t ptr, byval y as ulong         , byval r as ulong     ptr)
Declare sub u128modll(byval x as uint128_t ptr, byval y as ulongint      , byval r as ulongint  ptr)
Declare sub u128mul  (byval x as uint128_t ptr, byval y as uint128_t ptr , byval r as uint128_t ptr)
Declare sub u128mull (byval x as uint128_t ptr, byval y as ulong         , byval r as uint128_t ptr)
Declare sub u128mulll(byval x as uint128_t ptr, byval y as ulongint      , byval r as uint128_t ptr)
Declare sub u128sub  (byval x as uint128_t ptr, byval y as uint128_t ptr , byval r as uint128_t ptr)
Declare sub u128subl (byval x as uint128_t ptr, byval y as ulong         , byval r as uint128_t ptr)
Declare sub u128subll(byval x as uint128_t ptr, byval y as ulongint      , byval r as uint128_t ptr)
Declare sub li128div (byval x as long         , byval y as int128_t  ptr , byval r as int128_t  ptr)
Declare sub li128mul (byval x as long         , byval y as int128_t  ptr , byval r as int128_t  ptr)
Declare sub li128sub (byval x as long         , byval y as int128_t  ptr , byval r as int128_t  ptr)
Declare sub lu128add (byval x as ulong        , byval y as uint128_t ptr , byval r as uint128_t ptr)
Declare sub lu128div (byval x as ulong        , byval y as uint128_t ptr , byval r as uint128_t ptr)
Declare sub lu128mul (byval x as ulong        , byval y as uint128_t ptr , byval r as uint128_t ptr)
Declare sub lu128sub (byval x as ulong        , byval y as uint128_t ptr , byval r as uint128_t ptr)
Declare sub lli128div(byval x as longint      , byval y as int128_t  ptr , byval r as int128_t  ptr)
Declare sub lli128mul(byval x as longint      , byval y as int128_t  ptr , byval r as int128_t  ptr)
Declare sub lli128sub(byval x as longint      , byval y as int128_t  ptr , byval r as int128_t  ptr)
Declare sub llu128add(byval x as ulongint     , byval y as uint128_t ptr , byval r as uint128_t ptr)
Declare sub llu128div(byval x as ulongint     , byval y as uint128_t ptr , byval r as uint128_t ptr)
Declare sub llu128mul(byval x as ulongint     , byval y as uint128_t ptr , byval r as uint128_t ptr)
Declare sub llu128sub(byval x as ulongint     , byval y as uint128_t ptr , byval r as uint128_t ptr)
Declare sub i128shl  (byval x as int128_t  ptr, byval y as long          , byval r as int128_t  ptr)
Declare sub i128shr  (byval x as int128_t  ptr, byval y as long          , byval r as int128_t  ptr)
Declare sub i128or   (byval x as int128_t  ptr, byval y as int128_t  ptr , byval r as int128_t  ptr)
Declare sub i128xor  (byval x as int128_t  ptr, byval y as int128_t  ptr , byval r as int128_t  ptr)
Declare sub i128and  (byval x as int128_t  ptr, byval y as int128_t  ptr , byval r as int128_t  ptr)
Declare sub i128not  (byval x as int128_t  ptr, byval r as int128_t  ptr)
Declare sub u128not  (byval x as uint128_t ptr, byval r as uint128_t ptr)
Declare sub u128or   (byval x as uint128_t ptr, byval y as uint128_t ptr , byval r as uint128_t ptr)
Declare sub u128shl  (byval x as uint128_t ptr, byval y as long          , byval r as uint128_t ptr)
Declare sub u128shr  (byval x as uint128_t ptr, byval y as long          , byval r as uint128_t ptr)
Declare sub u128xor  (byval x as uint128_t ptr, byval y as uint128_t ptr , byval r as uint128_t ptr)
Declare sub i128neg  (byval x as int128_t  ptr, byval r as int128_t  ptr)
Declare sub i128abs  (byval x as int128_t  ptr, byval r as int128_t  ptr)

declare function u64clz(byval x as ulongint) as long

end extern
declare Operator <> ( Byref lhs As uint128_t, Byref rhs As uint128_t ) As long
declare Operator / ( Byref lhs As uint128_t, Byval rhs As ulong ) As uint128_t
declare Operator mod ( Byref lhs As uint128_t, Byval rhs As ulong ) As ulong
declare Operator = ( Byref lhs As int128_t, Byref rhs As int128_t ) As long
declare Operator = ( Byref lhs As uint128_t, Byref rhs As uint128_t ) As long

function u128toa(byval n as uint128_t) as string
	if n=0 then return "0"
	dim as string s=""
	dim as ulong r
	while n<>0
		r=n mod 10
		s=str(r)+s
		n=n/10
	wend
	return s
end function

function i128toa(byval n as int128_t) as string
	if n=0 then return "0"
	dim as string sign="",s=""
	dim as uint128_t m
	if bit(n.h,63) then
		sign="-"
		i128not(@n,@n)
		i128addl(@n,1,@n)
	end if
	m.l=n.l : m.h=n.h
	s=u128toa(m)
	return sign+s
end function

function uatoq(byval s as string) as uint128_t
	dim as uint128_t n, t, c
	dim as long i
	s=ltrim(rtrim(s))
	if left(s,1)="-" or left(s,1)="+" then
		s=mid(s,2)
	end if
	t.l=10 : t.h=0
	n.l=0 : n.h=0
	for i=0 to len(s)-1
		u128mul(@n,@t,@n)
		c.l=s[i]-48 : c.h=0
		u128add(@n,@c,@n)
	next
	return n
end function

function satoq(byval s as string) as int128_t
	dim as int128_t n, t, c
	dim as long i, sign=0
	s=ltrim(rtrim(s))
	if left(s,1)="-" then
		sign=1
		s=mid(s,2)
	end if
	if left(s,1)="+" then s=mid(s,2)
	t.l=10 : t.h=0
	n.l=0 : n.h=0
	for i=0 to len(s)-1
		i128mul(@n,@t,@n)
		c.l=s[i]-48 : c.h=0
		i128add(@n,@c,@n)
	next
	if sign then
		i128not(@n, @n)
		i128addl(@n,1,@n)
	end if
	return n
end function

Constructor int128_t ( )
	this.l=0
	this.h=0
End Constructor

Constructor int128_t ( Byval rhs As Long )
	if rhs<0 then
		this.l=-rhs
		this.h=0
		i128not(@this,@this)
		i128addl(@this,1,@this)
	else
		this.l=rhs
		this.h=0
	end if
End Constructor

Constructor int128_t ( Byref rhs As String )
	this=satoq(rhs)
End Constructor

Constructor int128_t ( Byref rhs As int128_t )
	this.l=rhs.l
	this.h=rhs.h
End Constructor

Constructor int128_t ( Byval rhs As LongInt )
	if rhs<0 then
		this.l=-rhs
		this.h=0
		i128not(@this,@this)
		i128addl(@this,1,@this)
	else
		this.l=rhs
		this.h=0
	end if
End Constructor

Destructor int128_t ( )
End Destructor

Operator int128_t.let ( Byref rhs As int128_t )
	this.l=rhs.l
	this.h=rhs.h
End Operator

Operator int128_t.let ( Byval rhs As Long )
	if rhs<0 then
		this.l=-rhs
		this.h=0
		i128not(@this,@this)
		i128addl(@this,1,@this)
	else
		this.l=rhs
		this.h=0
	end if
End Operator

Operator int128_t.let ( Byref rhs As String )
	this=satoq(rhs)
End Operator

Operator int128_t.Let ( Byval rhs As LongInt )
	if rhs<0 then
		this.l=-rhs
		this.h=0
		i128not(@this,@this)
		i128addl(@this,1,@this)
	else
		this.l=rhs
		this.h=0
	end if
End Operator

Operator int128_t.cast ( ) As String
	Operator = i128toa(this)
End Operator

Operator int128_t.cast ( ) As Long
	Operator = this.l
End Operator

'=================================================================
Constructor uint128_t ( )
	this.l=0
	this.h=0
End Constructor

Constructor uint128_t ( Byval rhs As uLong )
	this.l=rhs
	this.h=0
End Constructor

Constructor uint128_t ( Byref rhs As String )
	this=uatoq(rhs)
End Constructor

Constructor uint128_t ( Byref rhs As uint128_t )
	this.l=rhs.l
	this.h=rhs.h
End Constructor

Constructor uint128_t ( Byval rhs As uLongInt )
	this.l=rhs
	this.h=0
End Constructor

Destructor uint128_t ( )
End Destructor

Operator uint128_t.let ( Byref rhs As uint128_t )
	this.l=rhs.l
	this.h=rhs.h
End Operator

Operator uint128_t.let ( Byval rhs As uLong )
	this.l=rhs
	this.h=0
End Operator

Operator uint128_t.let ( Byref rhs As String )
	this=uatoq(rhs)
End Operator

Operator uint128_t.Let ( Byval rhs As uLongInt )
	this.l=rhs
	this.h=0
End Operator

Operator uint128_t.cast ( ) As String
	Operator = u128toa(this) '*uqtoa(this)
End Operator

Operator uint128_t.cast ( ) As uLong
	Operator = this.l
End Operator

'=================================================================
operator shl (byval lhs as int128_t, byval rhs as long) as int128_t
	dim as int128_t ret
	i128shl(@lhs, rhs, @ret)
	return ret
end operator

operator shl (byval lhs as uint128_t, byval rhs as long) as uint128_t
	dim as uint128_t ret
	u128shl(@lhs, rhs, @ret)
	return ret
end operator

operator shr (byval lhs as int128_t, byval rhs as long) as int128_t
	dim as int128_t ret
	i128shr(@lhs, rhs, @ret)
	return ret
end operator

operator shr (byval lhs as uint128_t, byval rhs as long) as uint128_t
	dim as uint128_t ret
	u128shr(@lhs, rhs, @ret)
	return ret
end operator

operator or (byval lhs as int128_t, byval rhs as int128_t) as int128_t
	dim as int128_t ret
	i128or(@lhs, @rhs, @ret)
	return ret
end operator

operator or (byval lhs as uint128_t, byval rhs as uint128_t) as uint128_t
	dim as uint128_t ret
	u128or(@lhs, @rhs, @ret)
	return ret
end operator

operator and (byval lhs as int128_t, byval rhs as int128_t) as int128_t
	dim as int128_t ret
	i128and(@lhs, @rhs, @ret)
	return ret
end operator

operator and (byval lhs as uint128_t, byval rhs as uint128_t) as uint128_t
	dim as uint128_t ret
	u128and(@lhs, @rhs, @ret)
	return ret
end operator

operator xor (byval lhs as int128_t, byval rhs as int128_t) as int128_t
	dim as int128_t ret
	i128xor(@lhs, @rhs, @ret)
	return ret
end operator

operator xor (byval lhs as uint128_t, byval rhs as uint128_t) as uint128_t
	dim as uint128_t ret
	u128xor(@lhs, @rhs, @ret)
	return ret
end operator

operator not (byval lhs as int128_t) as int128_t
	dim as int128_t ret
	i128not(@lhs, @ret)
	return ret
end operator

operator not (byval lhs as uint128_t) as uint128_t
	dim as uint128_t ret
	u128not(@lhs, @ret)
	return ret
end operator
'================================================================
Operator + ( Byref lhs As int128_t, Byref rhs As int128_t ) As int128_t
	dim As int128_t result
	i128add(@lhs, @rhs, @result)
	Operator = result
End Operator

Operator + ( Byref lhs As int128_t, Byval rhs As long ) As int128_t
	Dim As int128_t result
	i128addl(@lhs, rhs, @result)
	Operator = result
End Operator

Operator + ( Byref lhs As int128_t, Byval rhs As longint ) As int128_t
	Dim As int128_t result
	i128addll(@lhs, rhs, @result)
	Operator = result
End Operator

Operator + ( Byref lhs As Long, Byval rhs As int128_t ) As int128_t
	Dim As int128_t result
	li128add(lhs, @rhs, @result)
	Operator = result
End Operator

Operator + ( Byref lhs As Longint, Byval rhs As int128_t ) As int128_t
	Dim As int128_t result
	lli128add(lhs, @rhs, @result)
	Operator = result
End Operator

/'
Operator - ( Byref rhs As int128_t ) As int128_t
	Dim As int128_t result=rhs
	i128not(@result, @result)
	i128addl(@result, 1, @result)
	Operator = result
End Operator
'/
Operator - ( Byref rhs As int128_t ) As int128_t
	Dim As int128_t result
	i128neg(@rhs, @result)
	Operator = result
End Operator

Operator - ( Byref lhs As int128_t, Byref rhs As int128_t ) As int128_t
	dim As int128_t result
	i128sub(@lhs, @rhs, @result)
	Operator = result
End Operator

Operator - ( Byref lhs As int128_t, Byval rhs As long ) As int128_t
	Dim As int128_t result
	i128subl(@lhs, rhs, @result)
	Operator = result
End Operator

Operator - ( Byref lhs As int128_t, Byval rhs As longint ) As int128_t
	Dim As int128_t result
	i128subll(@lhs, rhs, @result)
	Operator = result
End Operator

Operator - ( Byref lhs As Long, Byval rhs As int128_t ) As int128_t
	Dim As int128_t result
	li128sub(lhs, @rhs, @result)
	Operator = result
End Operator

Operator - ( Byref lhs As Longint, Byval rhs As int128_t ) As int128_t
	Dim As int128_t result
	lli128sub(lhs, @rhs, @result)
	Operator = result
End Operator

Operator * ( Byref lhs As int128_t, Byref rhs As int128_t ) As int128_t
	dim As int128_t result
	i128mul(@lhs, @rhs, @result)
	Operator = result
End Operator

Operator * ( Byref lhs As int128_t, Byval rhs As long ) As int128_t
	Dim As int128_t result
	i128mull(@lhs, rhs, @result)
	Operator = result
End Operator

Operator * ( Byref lhs As int128_t, Byval rhs As longint ) As int128_t
	Dim As int128_t result
	i128mulll(@lhs, rhs, @result)
	Operator = result
End Operator

Operator * ( Byref lhs As Long, Byval rhs As int128_t ) As int128_t
	Dim As int128_t result
	li128mul(lhs, @rhs, @result)
	Operator = result
End Operator

Operator * ( Byref lhs As Longint, Byval rhs As int128_t ) As int128_t
	Dim As int128_t result
	lli128mul(lhs, @rhs, @result)
	Operator = result
End Operator

Operator / ( Byref lhs As int128_t, Byref rhs As int128_t ) As int128_t
	dim As int128_t result
	i128div(@lhs, @rhs, @result)
	Operator = result
End Operator

Operator / ( Byref lhs As int128_t, Byval rhs As long ) As int128_t
	Dim As int128_t result
	i128divl(@lhs, rhs, @result)
	Operator = result
End Operator

Operator / ( Byref lhs As int128_t, Byval rhs As longint ) As int128_t
	Dim As int128_t result
	i128divll(@lhs, rhs, @result)
	Operator = result
End Operator

Operator / ( Byref lhs As Long, Byval rhs As int128_t ) As int128_t
	Dim As int128_t result
	li128div(lhs, @rhs, @result)
	Operator = result
End Operator

Operator / ( Byref lhs As Longint, Byval rhs As int128_t ) As int128_t
	Dim As int128_t result
	lli128div(lhs, @rhs, @result)
	Operator = result
End Operator

Operator mod ( Byref lhs As int128_t, Byval rhs As long ) As long
	Dim As long result
	i128mod(@lhs, rhs, @result)
	Operator = result
End Operator

Operator mod ( Byref lhs As int128_t, Byval rhs As longint ) As longint
	Dim As longint result
	i128modll(@lhs, rhs, @result)
	Operator = result
End Operator

function i128cmp( Byref lhs As int128_t, Byref rhs As int128_t ) as long
	dim as int128_t cmp
	i128sub(@lhs, @rhs, @cmp)
	if cmp.h=0 andalso cmp.l=0 then
		return 0
	elseif bit(cmp.h,63) then
		return -1
	else
		return 1
	end if
end function

Operator = ( Byref lhs As int128_t, Byref rhs As int128_t ) As long
	Operator = (i128cmp(lhs, rhs) = 0)
End Operator

Operator < ( Byref lhs As int128_t, Byref rhs As int128_t ) As long
	Operator = (i128cmp(lhs, rhs) < 0)
End Operator

Operator > ( Byref lhs As int128_t, Byref rhs As int128_t ) As long
	Operator = (i128cmp(lhs, rhs) > 0)
End Operator

Operator <= ( Byref lhs As int128_t, Byref rhs As int128_t ) As long
	Operator = (i128cmp(lhs, rhs) <= 0)
End Operator

Operator >= ( Byref lhs As int128_t, Byref rhs As int128_t ) As long
	Operator = (i128cmp(lhs, rhs) >= 0)
End Operator

Operator <> ( Byref lhs As int128_t, Byref rhs As int128_t ) As long
	Operator = (i128cmp(lhs, rhs) <> 0)
End Operator

'================================================================
Operator + ( Byref lhs As uint128_t, Byref rhs As uint128_t ) As uint128_t
	dim As uint128_t result
	u128add(@lhs, @rhs, @result)
	Operator = result
End Operator

Operator + ( Byref lhs As uint128_t, Byval rhs As Ulong ) As uint128_t
	Dim As uint128_t result
	u128addl(@lhs, rhs, @result)
	Operator = result
End Operator

Operator + ( Byref lhs As uint128_t, Byval rhs As Ulongint ) As uint128_t
	Dim As uint128_t result
	u128addll(@lhs, rhs, @result)
	Operator = result
End Operator

Operator + ( Byref lhs As Ulong, Byval rhs As uint128_t ) As uint128_t
	Dim As uint128_t result
	lu128add(lhs, @rhs, @result)
	Operator = result
End Operator

Operator + ( Byref lhs As Ulongint, Byval rhs As uint128_t ) As uint128_t
	Dim As uint128_t result
	llu128add(lhs, @rhs, @result)
	Operator = result
End Operator

Operator - ( Byref rhs As uint128_t ) As uint128_t
	Dim As uint128_t result=rhs
	u128not(@result, @result)
	Operator = result
End Operator

Operator - ( Byref lhs As uint128_t, Byref rhs As uint128_t ) As uint128_t
	dim As uint128_t result
	u128sub(@lhs, @rhs, @result)
	Operator = result
End Operator

Operator - ( Byref lhs As uint128_t, Byval rhs As Ulong ) As uint128_t
	Dim As uint128_t result
	u128subl(@lhs, rhs, @result)
	Operator = result
End Operator

Operator - ( Byref lhs As uint128_t, Byval rhs As Ulongint ) As uint128_t
	Dim As uint128_t result
	u128subll(@lhs, rhs, @result)
	Operator = result
End Operator

Operator - ( Byref lhs As Ulong, Byval rhs As uint128_t ) As uint128_t
	Dim As uint128_t result
	lu128sub(lhs, @rhs, @result)
	Operator = result
End Operator

Operator - ( Byref lhs As Ulongint, Byval rhs As uint128_t ) As uint128_t
	Dim As uint128_t result
	llu128sub(lhs, @rhs, @result)
	Operator = result
End Operator

Operator * ( Byref lhs As uint128_t, Byref rhs As uint128_t ) As uint128_t
	dim As uint128_t result
	u128mul(@lhs, @rhs, @result)
	Operator = result
End Operator

Operator * ( Byref lhs As uint128_t, Byval rhs As Ulong ) As uint128_t
	Dim As uint128_t result
	u128mull(@lhs, rhs, @result)
	Operator = result
End Operator

Operator * ( Byref lhs As uint128_t, Byval rhs As Ulongint ) As uint128_t
	Dim As uint128_t result
	u128mulll(@lhs, rhs, @result)
	Operator = result
End Operator

Operator * ( Byref lhs As Ulong, Byval rhs As uint128_t ) As uint128_t
	Dim As uint128_t result
	lu128mul(lhs, @rhs, @result)
	Operator = result
End Operator

Operator * ( Byref lhs As Ulongint, Byval rhs As uint128_t ) As uint128_t
	Dim As uint128_t result
	llu128mul(lhs, @rhs, @result)
	Operator = result
End Operator

Operator / ( Byref lhs As uint128_t, Byref rhs As uint128_t ) As uint128_t
	dim As uint128_t result
	u128div(@lhs, @rhs, @result)
	Operator = result
End Operator

Operator / ( Byref lhs As uint128_t, Byval rhs As Ulong ) As uint128_t
	Dim As uint128_t result
	u128divl(@lhs, rhs, @result)
	Operator = result
End Operator

Operator / ( Byref lhs As uint128_t, Byval rhs As Ulongint ) As uint128_t
	Dim As uint128_t result
	u128divll(@lhs, rhs, @result)
	Operator = result
End Operator

Operator / ( Byref lhs As Ulong, Byval rhs As uint128_t ) As uint128_t
	Dim As uint128_t result
	lu128div(lhs, @rhs, @result)
	Operator = result
End Operator

Operator / ( Byref lhs As Ulongint, Byval rhs As uint128_t ) As uint128_t
	Dim As uint128_t result
	llu128div(lhs, @rhs, @result)
	Operator = result
End Operator

Operator mod ( Byref lhs As uint128_t, Byval rhs As ulong ) As ulong
	Dim As ulong result
	u128mod(@lhs, rhs, @result)
	Operator = result
End Operator

Operator mod ( Byref lhs As uint128_t, Byval rhs As ulongint ) As ulongint
	Dim As ulongint result
	u128modll(@lhs, rhs, @result)
	Operator = result
End Operator

function u128cmp( Byref lhs As uint128_t, Byref rhs As uint128_t ) as long
	dim as uint128_t cmp
	u128sub(@lhs, @rhs, @cmp)
	if cmp.h=0 andalso cmp.l=0 then
		return 0
	elseif bit(cmp.h,63) then
		return -1
	else
		return 1
	end if
end function

Operator = ( Byref lhs As uint128_t, Byref rhs As uint128_t ) As long
	Operator = (u128cmp(lhs, rhs) = 0)
End Operator

Operator < ( Byref lhs As uint128_t, Byref rhs As uint128_t ) As long
	Operator = (u128cmp(lhs, rhs) < 0)
End Operator

Operator > ( Byref lhs As uint128_t, Byref rhs As uint128_t ) As long
	Operator = (u128cmp(lhs, rhs) > 0)
End Operator

Operator <= ( Byref lhs As uint128_t, Byref rhs As uint128_t ) As long
	Operator = (u128cmp(lhs, rhs) <= 0)
End Operator

Operator >= ( Byref lhs As uint128_t, Byref rhs As uint128_t ) As long
	Operator = (u128cmp(lhs, rhs) >= 0)
End Operator

Operator <> ( Byref lhs As uint128_t, Byref rhs As uint128_t ) As long
	Operator = (u128cmp(lhs, rhs) <> 0)
End Operator

Operator int128_t.for ( )
End Operator
 
Operator int128_t.step ( )
        this += 1 'this = this+1 '
End Operator 
 
Operator int128_t.next ( Byref end_cond As int128_t ) As Integer
        Return this <= end_cond
End Operator
 
 
'' explicit step versions
'' 
Operator int128_t.for ( Byref step_var As int128_t )
End Operator
 
Operator int128_t.step ( Byref step_var As int128_t )
        this = this+step_var 'this = this + step_var '    
End Operator 
 
Operator int128_t.next ( Byref end_cond As int128_t, Byref step_var As int128_t ) As Integer
        If step_var < 0 Then
                Return this >= end_cond
        Else
                Return this <= end_cond
        End If
End Operator
'=======================================================================
Operator uint128_t.for ( )
End Operator
 
Operator uint128_t.step ( )
        this += 1 'this = this+1 '
End Operator 
 
Operator uint128_t.next ( Byref end_cond As uint128_t ) As Integer
        Return this <= end_cond
End Operator
 
 
'' explicit step versions
'' 
Operator uint128_t.for ( Byref step_var As uint128_t )
End Operator
 
Operator uint128_t.step ( Byref step_var As uint128_t )
        this = this+step_var 'this = this + step_var '    
End Operator 
 
Operator uint128_t.next ( Byref end_cond As uint128_t, Byref step_var As uint128_t ) As Integer
        If step_var < 0 Then
                Return this >= end_cond
        Else
                Return this <= end_cond
        End If
End Operator

function hex (byref rhs as int128_t) as string
	return hex(rhs.h,16)+hex(rhs.l,16)
end function

function hex (byref rhs as uint128_t) as string
	return hex(rhs.h,16)+hex(rhs.l,16)
end function

function bin (byref rhs as int128_t) as string
	return bin(rhs.h,64)+bin(rhs.l,64)
end function

function bin (byref rhs as uint128_t) as string
	return bin(rhs.h,64)+bin(rhs.l,64)
end function

operator abs (byref rhs as int128_t) as int128_t
	dim as int128_t result
	i128abs(@rhs, @result)
	return result
end operator

function i128powl(byref x as int128_t, byval e as uLong) as int128_t
	'take x to an Long power
	dim as int128_t z, y = x
	dim as Long n
	n = abs(e)
	z.l=1 : z.h=0
	while n>0
		while (bit(n,0)=0)
			n=n\2
			i128mul(@y, @y, @y)
		wend
		n=n-1
		i128mul(@z, @y, @z)
	wend
	return z
end function

function u128powl(byref x as uint128_t, byval e as uLong) as uint128_t
	'take x to an Long power
	dim as uint128_t z, y = x
	dim as Long n
	n = abs(e)
	z.l=1 : z.h=0
	while n>0
		while (bit(n,0)=0)
			n=n\2
			u128mul(@y, @y, @y)
		wend
		n=n-1
		u128mul(@z, @y, @z)
	wend
	return z
end function

Operator ^ ( Byref lhs As int128_t, Byref rhs As ulong ) As int128_t
    Return i128powl(lhs, rhs )
End Operator

Operator ^ ( Byref lhs As uint128_t, Byref rhs As ulong ) As uint128_t
    Return u128powl(lhs, rhs )
End Operator
small example

Code: Select all

#include "int128.bi"

dim as uint128_t x, n
dim as int128_t  y

n="170141183460469231731687303715884105728"
x="340282366920938463463374607431768211455"
y="170141183460469231731687303715884105728"

? hex(n)
? hex(x)
? hex(y)
? bin(n)
? bin(x)
? bin(y)

? n
? x
? y
for z as uint128_t=0 to 20
	? z, z^z
next
Last edited by srvaldez on Jun 16, 2017 0:09, edited 4 times in total.
deltarho[1859]
Posts: 4292
Joined: Jan 02, 2017 0:34
Location: UK
Contact:

Re: int128

Post by deltarho[1859] »

I'm getting a failed compilation with c128.bas

F:\Downloads\FreeBASIC-1.05.0-win64\bin\win64\ld.exe: cannot find -l128
linking failed: 'F:\Downloads\FreeBASIC-1.05.0-win64\bin\win64\ld.exe' terminated with exit code 1
St_W
Posts: 1619
Joined: Feb 11, 2009 14:24
Location: Austria
Contact:

Re: int128

Post by St_W »

deltarho[1859] wrote:ld.exe: cannot find -l128
That means that the linker cannot find the library "128". By default it searches for a file called "128.dll"/"lib128.dll.a" or "lib128.a" on Windows. The search path includes FreeBasic's "lib" folder as well as the directory of the source code. You can add library search paths via fbc command line.

So please ensure that you have "lib128.a" (if you want to link statically) or "128.dll" (if you want to link dynamically) and that the linker can find it.
deltarho[1859]
Posts: 4292
Joined: Jan 02, 2017 0:34
Location: UK
Contact:

Re: int128

Post by deltarho[1859] »

You keep rescuing me, St_W, thank you.

I'm afraid "you can use either the dll or static lib" went right over my head. My PowerBASIC background is showing again. <smile>

All is well now.
srvaldez
Posts: 3373
Joined: Sep 25, 2005 21:54

Re: int128

Post by srvaldez »

hello deltarho[1859], I added a few more functions, it should be complete as far as I am concerned.
regarding where to place the lib and dll, my preference is to place a lib in the FB lib folder and if using a dll in the same place where the exe that is using it resides.
srvaldez
Posts: 3373
Joined: Sep 25, 2005 21:54

Re: int128

Post by srvaldez »

just for fun, a binary shift division, about 70 times slower than the C version.

Code: Select all

#include "int128.bi"

function msbit1(Byref n As uint128_t) as ulong
	'returns the highest bit set plus 1
	'so for the value of 1 it returns 1 instead of 0
	if n.h=0 andalso n.l=0 then return 0
	return iif((n.h > 0),128-u64clz(n.h) , 64-u64clz(n.l))
end function

function bin_div(Byval lhs As uint128_t, Byval rhs As uint128_t) As uint128_t
	dim as long lhs_msb, rhs_msb, shift_count
	dim as uint128_t q=0', r=0
	lhs_msb=msbit1(lhs)
	rhs_msb=msbit1(rhs)
	if lhs_msb=0 then return 0
	if rhs_msb=1 then return lhs
	if lhs_msb<rhs_msb then return 0
	shift_count=lhs_msb-rhs_msb
	rhs=rhs shl shift_count
	for i as long=0 to shift_count
		q=q shl 1
		if rhs<=lhs then
			lhs=lhs-rhs
			q=q+1
			rhs=rhs shr 1
		else
			rhs=rhs shr 1
		end if
		shift_count-=1
	next
	return q
end function

dim as uint128_t  x, y, z
dim as double t,t2
x="12345678901234567890123456789012345678"

t=timer
for y as uint128_t = 1 to 1000000
	z = bin_div(x,y)
next
t=timer-t
t2=timer
for y as uint128_t = 1 to 1000000
	z = x/y
next
t2=timer-t2
print t,t2,t/t2
Last edited by srvaldez on Jun 16, 2017 0:10, edited 2 times in total.
deltarho[1859]
Posts: 4292
Joined: Jan 02, 2017 0:34
Location: UK
Contact:

Re: int128

Post by deltarho[1859] »

What I wanted to do was copy, paste, compile and run and then look at your code to see what you are doing.

However, it won't even compile and I don't have the time to fathom out why not.
Post Reply