CInt96 - 96 bit integer data type

User projects written in or related to FreeBASIC.
deltarho[1859]
Posts: 4292
Joined: Jan 02, 2017 0:34
Location: UK
Contact:

Re: CInt96 - 96 bit integer dta type

Post by deltarho[1859] »

@srvaldez

Magic! You passed the interview - when can you start? <smile>

Tried this:

Code: Select all

DIM AS CInt96 big

big = 1
For k As Long=1 to 95
   Print  k,shift_left96( big,k)
Next
Print "******************"
big="79228162514264337593543950335"
For k As Long=1 to 95
   Print  k,shift_right96( big,k)
Next

Sleep
I thought it might be slow - but it belts along. Printing to the console is time-consuming so that number crunching is fast.

Crunch and print were over in 111ms.

Not bad for a 'barely functioning' brain. <laugh>
fxm
Moderator
Posts: 12083
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Re: CInt96 - 96 bit integer dta type

Post by fxm »

One cannot transform your function into the 'Shl' operator because such operators do not support recursion, but one can declare a 'Shl' operator that calls this function:

Code: Select all

operator shl(byref n as CInt96, byref k as long) as CInt96
   return shift_left96(n, k)
end operator

dim as CInt96 big=8
for k as long=1 to 92
   print  k, big shl k
next
srvaldez
Posts: 3373
Joined: Sep 25, 2005 21:54

Re: CInt96 - 96 bit integer dta type

Post by srvaldez »

thank you fxm, was not aware that recursion was not allowed in operators, but your solution works. :-)
the or, xor, and operators are very simple and should be no problem.
deltarho[1859]
Posts: 4292
Joined: Jan 02, 2017 0:34
Location: UK
Contact:

Re: CInt96 - 96 bit integer dta type

Post by deltarho[1859] »

Come to think of it I'd prefer CUint96.
fxm
Moderator
Posts: 12083
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Re: CInt96 - 96 bit integer dta type

Post by fxm »

fxm wrote:One cannot transform your function into the 'Shl' operator because such operators do not support recursion
In fact, it works.
I should have tried it before thinking that the binary operators did not support recursion!

Code: Select all

operator shl(byval n as CInt96, byval k as long) as CInt96

   dim as ulong a, b, c
   a=n.m_int96.Hi32
   b=n.m_int96.Mid32
   c=(n.m_int96.Lo64 shl 32 ) shr 32
   if k<=96 then
      if k>=32 then
         a=b
         b=c
         c=0
         n.m_int96.Hi32=a
         n.m_int96.Lo64=c
         n.m_int96.Mid32=b
         return n shl (k-32)
      else
         if k=0 then
            return n
         else
            a=(a shl k) or (b shr (32 - k))
            b = (b shl k) or (c shr (32 - k))
            c = c shl k
            
            n.m_int96.Hi32=a
            n.m_int96.Lo64=c
            n.m_int96.Mid32=b
         end if
      end if
   end if
   return n
end operator
Josep Roca
Posts: 564
Joined: Sep 27, 2016 18:20
Location: Valencia, Spain

Re: CInt96 - 96 bit integer dta type

Post by Josep Roca »

- 'Return' calls the copy-constructor while 'Function =' calls the let-operator but as the two procedures have the same code, so the problem is not coming for here!
When I started using Free Basic, I had a problem with a class for not knowing this very important distinction. I had implemented a copy constructor, but not a LET operator. Therefore, I wrongly thought that there was a problem with FUNCTION= because the methods that used RETURN worked fine but the ones that used FUNCTION= don't.
srvaldez
Posts: 3373
Joined: Sep 25, 2005 21:54

Re: CInt96 - 96 bit integer dta type

Post by srvaldez »

here are the or, xor, and, not functions.

Code: Select all

operator shl(byval n as CInt96, byval k as long) as CInt96
	dim as ulong a, b, c
	a=n.m_int96.Hi32
	b=n.m_int96.Mid32
	c=(n.m_int96.Lo64 shl 32 ) shr 32
	if k<=96 then
		if k>=32 then
			a=b
			b=c
			c=0
			n.m_int96.Hi32=a
			n.m_int96.Lo64=c
			n.m_int96.Mid32=b
			return n shl (k-32)
		else
			if k=0 then
				return n
			else
				a=(a shl k) or (b shr (32 - k))
				b = (b shl k) or (c shr (32 - k))
				c = c shl k
				
				n.m_int96.Hi32=a
				n.m_int96.Lo64=c
				n.m_int96.Mid32=b
			end if
		end if
	end if
	return n
end operator

' ========================================================================================

operator shr(byval n as CInt96, byval k as long) as CInt96
	dim as ulong a, b, c
	a=n.m_int96.Hi32
	b=n.m_int96.Mid32
	c=(n.m_int96.Lo64 shl 32 ) shr 32
	if k<=96 then
		if k>=32 then
			c = b
			b = a
			a = 0
			n.m_int96.Hi32=a
			n.m_int96.Lo64=c
			n.m_int96.Mid32=b
			return n shr (k-32)
		else
			if k=0 then
				return n
			else
				c = (b shl (32-k)) or (c shr k)
				b = (a shl (32-k)) or (b shr k)
				a = a shr k
				
				n.m_int96.Hi32=a
				n.m_int96.Lo64=c
				n.m_int96.Mid32=b
			end if
		end if
	end if
	return n
end operator

' ========================================================================================

operator sqr(byval n as CInt96) as CInt96
	dim as CInt96 r=sqr(n)
	while r*r>n
		r-=1
	wend
	while n-r*r>r*2
		r+=1
	wend
	return r
end operator

' ========================================================================================

operator and(byval n as CInt96, byval m as CInt96) as CInt96
	n.m_int96.Hi32 and=m.m_int96.Hi32
	n.m_int96.Lo64 and=m.m_int96.Lo64
	return n
end operator

' ========================================================================================

operator or(byval n as CInt96, byval m as CInt96) as CInt96
	n.m_int96.Hi32 or=m.m_int96.Hi32
	n.m_int96.Lo64 or=m.m_int96.Lo64
	return n
end operator

' ========================================================================================

operator xor(byval n as CInt96, byval m as CInt96) as CInt96
	n.m_int96.Hi32 xor=m.m_int96.Hi32
	n.m_int96.Lo64 xor=m.m_int96.Lo64
	return n
end operator

operator not(byval n as CInt96) as CInt96
	n.m_int96.Hi32=not n.m_int96.Hi32
	n.m_int96.Lo64=not n.m_int96.Lo64
	return n
end operator
srvaldez
Posts: 3373
Joined: Sep 25, 2005 21:54

Re: CInt96 - 96 bit integer data type

Post by srvaldez »

please check my code for errors or improvements
thanks in advance

Code: Select all

operator shl(byval n as CInt96, byval k as long) as CInt96
/' 
type tagDEC
   wReserved as USHORT

   union
      type
         scale as UBYTE
         sign as UBYTE
      end type

      signscale as USHORT
   end union

   Hi32 as ULONG

   union
      type
         Lo32 as ULONG
         Mid32 as ULONG
      end type

      Lo64 as ULONGLONG
   end union
end type

type DECIMAL as tagDEC
'/
/'
TYPE CInt96
   m_int96 AS DECIMAL   ' // The underlying DECIMAL structure
END TYPE
'/
'CInt96 type has three members inherited from Decimal
'm_int96.Hi32 as ulong
'union
'	m_int96.Mid32 as ulong
'	m_int96.Lo64 as ulongint
'end union
'so m_int96.Mid32 = high32-bits of m_int96.Lo64
'                                  ---------m_int96.Mid32----------
'----------m_int96.Hi32----------  -------------------------m_int96.Lo64-----------------------------
'11111111111111111111111111111111  11111111111111111111111111111111  11111111111111111111111111111111
'

	if k<96 then
		if k<32 then
			n.m_int96.Hi32=(n.m_int96.Hi32 shl k) or (n.m_int96.Lo64 shr (64-k))
			n.m_int96.Lo64=n.m_int96.Lo64 shl k
		elseif k=32 then
			n.m_int96.Hi32=n.m_int96.Mid32
			n.m_int96.Lo64=n.m_int96.Lo64 shl k
		elseif k>32 andalso k<64 then
			n.m_int96.Hi32=(n.m_int96.Mid32 shl (k-32)) or (n.m_int96.Lo64 shr (64-k))
			n.m_int96.Lo64=n.m_int96.Lo64 shl k
		elseif k>=64 then
			n.m_int96.Lo64=n.m_int96.Lo64 shl (k-32)
			n.m_int96.Hi32=n.m_int96.Mid32
			n.m_int96.Lo64=0
		end if
	else
		print "warning: Left-Shift value greater than or equal to number of bits in CInt96 type"
	end if
	return n
end operator

' ========================================================================================
operator shr(byval n as CInt96, byval k as long) as CInt96
/' 
type tagDEC
   wReserved as USHORT

   union
      type
         scale as UBYTE
         sign as UBYTE
      end type

      signscale as USHORT
   end union

   Hi32 as ULONG

   union
      type
         Lo32 as ULONG
         Mid32 as ULONG
      end type

      Lo64 as ULONGLONG
   end union
end type

type DECIMAL as tagDEC
'/
/'
TYPE CInt96
   m_int96 AS DECIMAL   ' // The underlying DECIMAL structure
END TYPE
'/
'CInt96 type has three members inherited from Decimal
'm_int96.Hi32 as ulong
'union
'	m_int96.Mid32 as ulong
'	m_int96.Lo64 as ulongint
'end union
'so m_int96.Mid32 = high32-bits of m_int96.Lo64
'                                  ---------m_int96.Mid32----------
'----------m_int96.Hi32----------  -------------------------m_int96.Lo64-----------------------------
'11111111111111111111111111111111  11111111111111111111111111111111  11111111111111111111111111111111
'
	dim as ulong midle
	if k<96 then
		if k<32 then
			midle=(n.m_int96.Hi32 shl (32-k)) or (n.m_int96.Mid32 shr k)
			n.m_int96.Hi32=n.m_int96.Hi32 shr k
			n.m_int96.Lo64=n.m_int96.Lo64 shr k
			n.m_int96.Mid32=midle
		elseif k=32 then
			n.m_int96.Lo64=n.m_int96.Lo64 shr k
			n.m_int96.Mid32=n.m_int96.Hi32
			n.m_int96.Hi32=0
		elseif k>32 then
			n.m_int96.Lo64=n.m_int96.Lo64 shr 32
			n.m_int96.Mid32=n.m_int96.Hi32
			n.m_int96.Lo64=n.m_int96.Lo64 shr (k-32)
			n.m_int96.Hi32=0
		end if
	else
		print "warning: Right-Shift value greater than or equal to number of bits in CInt96 type"
	end if
	return n
end operator
Post Reply