CInt96 - 96 bit integer data type

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

Re: CInt96 - 96 bit integer dta type

Postby deltarho[1859] » Sep 17, 2018 14:54

@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
Posts: 8890
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Re: CInt96 - 96 bit integer dta type

Postby fxm » Sep 17, 2018 15:10

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: 1877
Joined: Sep 25, 2005 21:54

Re: CInt96 - 96 bit integer dta type

Postby srvaldez » Sep 17, 2018 15:22

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: 1739
Joined: Jan 02, 2017 0:34
Location: UK

Re: CInt96 - 96 bit integer dta type

Postby deltarho[1859] » Sep 17, 2018 15:29

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

Re: CInt96 - 96 bit integer dta type

Postby fxm » Sep 17, 2018 15:35

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: 415
Joined: Sep 27, 2016 18:20
Location: Valencia, Spain

Re: CInt96 - 96 bit integer dta type

Postby Josep Roca » Sep 17, 2018 19:08

- '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: 1877
Joined: Sep 25, 2005 21:54

Re: CInt96 - 96 bit integer dta type

Postby srvaldez » Sep 17, 2018 19:37

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: 1877
Joined: Sep 25, 2005 21:54

Re: CInt96 - 96 bit integer data type

Postby srvaldez » Sep 23, 2018 15:45

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

Return to “Projects”

Who is online

Users browsing this forum: No registered users and 3 guests