Re: boolean sequence

new topic     » goto parent     » topic index » view thread      » older message » newer message

Tone Skoda wrote:

> Juergen Luethje wrote:
>
>> Also, since the whole thing is 1-based now, 0 could beused instead of -1,
>> in order to indicate, that find_byte_... didn't find the given value.
>> What do you think?
>
> i agree, same as eu's find ().

<snip>

>> Maybe I should add pack/unpack functions? Then the user can "unpack" a
>> byte array to a normal sequence, use any existing function that (s)he
>> wants, and then "re-pack" the normal sequence, to get again a byte
>> array.
>
> yes, pack and unpack functions will be also needed. i also thought of that
> later.

After I wrote the above text, I realized that the function for "packing"
a normal sequence is the same as the newassign_..() function, that you
proposed. smile

> your byte code from other post looks good. thanks.

Her comes the code regarding short integers, with find_..() modified the
way we talked about, and with additional functions new_..(), pack_..()
and unpack_..().

include misc.e     -- for pretty_print()
include bit.e      -- Eu 2.4 or later required

------------------------------------------------------------------------
-- utility functions

function ceil (object x)
   -- the opposite of floor()
   -- x may be an atom or a sequence
   return -floor(-x)
end function

------------------------------------------------------------------------
-- types

global type positive_int (object x)
   if integer(x) then
      return x > 0
   end if
   return 0
end type

type sequence_of_long (object x)
   -- sequence consisting of 32-bit integers (signed or unsigned)
   object t

   if atom(x) then return 0 end if
   for i = 1 to length(x) do
      t = x[i]
      if (not atom(t)) or (t != floor(t))
      or (t < -#80000000) or (#FFFFFFFF < t) then
         return 0
      end if
   end for
   return 1
end type

type short (object x)
   -- signed or unsigned 16-bit integer
   if integer(x) then
      if -#8000 <= x then
         return x <= #FFFF
      end if
   end if
   return 0
end type

type sequence_of_short (object x)
   -- sequence consisting of 16-bit integers (signed or unsigned)
   if atom(x) then return 0 end if
   for i = 1 to length(x) do
      if not short(x[i]) then
         return 0
      end if
   end for
   return 1
end type

------------------------------------------------------------------------
-- * The following functions let us treat sequences consisting of an
--   arbitrary number of 32-bit integers as huge "short integer arrays". *
-- Note: The lowest order short integer is always indexed by 1.

global function new_short (positive_int numShortInts)
   -- Create a new empty "short integer array".
   return repeat(0, ceil(numShortInts/2))
end function

global function put_short (sequence_of_long s, positive_int number, short val)
   -- Store 'val' in the short integer in 's', that is indexed by 'number'.
   -- It doesn't matter, whether 'val' is signed or unsigned
   -- (like with the built-in procedure poke4()).
   integer n

   n = ceil(number/2)
   if n > length(s) then
      return -1                   -- error
   end if

   s[n] = or_bits(s[n], c_func( SHIFT_LEFT, {and_bits(val, #FFFF),
                                remainder(number+1,2)*16} ))
   return s
end function

global function pack_short (sequence_of_short s)
   -- Create a new "short integer array", and assign the values in 's' to it.
   -- It doesn't matter, whether the values in 's' are signed or unsigned.
   sequence ret
   integer n

   ret = repeat(0, ceil(length(s)/2))
   for i = 1 to length(s) do
      n = ceil(i/2)
      ret[n] = or_bits(ret[n], c_func( SHIFT_LEFT, {and_bits(s[i], #FFFF),
                                       remainder(i+1,2)*16} ))
   end for
   return ret
end function

global function get_short_u (sequence_of_long s, positive_int number)
   -- Return the short integer in 's', that is indexed by 'number', as an
   -- *unsigned* value.
   integer n

   n = ceil(number/2)
   if n > length(s) then
      return {}                   -- error
   end if

return and_bits(c_func( SHIFT_RIGHT, {s[n], remainder(number+1,2)*16} ),
   #FFFF)
end function

global function get_short_s (sequence_of_long s, positive_int number)
   -- Return the short integer in 's', that is indexed by 'number', as a
   -- *signed* value.
   integer n, val

   n = ceil(number/2)
   if n > length(s) then
      return {}                   -- error
   end if

val = and_bits(c_func( SHIFT_RIGHT, {s[n], remainder(number+1,2)*16} ),
   #FFFF)
   if val > #7FFF then
      val -= #10000               -- convert to signed
   end if
   return val
end function

global function unpack_short_u (sequence_of_long s)
-- "Unpack" the values in a "short integer array" to a normal Euphoria
   sequence,
   -- treating the short integers as *unsigned* values.
   sequence ret
   integer n

   ret = repeat(0, length(s)*2)
   for i = 1 to length(ret) do
      n = ceil(i/2)
ret[i] = and_bits(c_func( SHIFT_RIGHT, {s[n], remainder(i+1,2)*16} ),
      #FFFF)
   end for
   return ret
end function

global function unpack_short_s (sequence_of_long s)
-- "Unpack" the values in a "short integer array" to a normal Euphoria
   sequence,
   -- treating the short integers as *signed* values.
   sequence ret
   integer n, val

   ret = repeat(0, length(s)*2)
   for i = 1 to length(ret) do
      n = ceil(i/2)
      val = and_bits(c_func( SHIFT_RIGHT, {s[n], remainder(i+1,2)*16} ), #FFFF)
      if val > #7FFF then
         val -= #10000            -- convert to signed
      end if
      ret[i] = val
   end for
   return ret
end function

global function find_short_forward (short val, sequence_of_long s)
   -- Return the number of the lowest order short integer in 's', that is equal
   -- to 'val' (or return -1, if 'val' is not found).
   -- It doesn't matter, whether 'val' is signed or unsigned.
   atom t

   if val < 0 then
      val += #10000               -- convert to unsigned
   end if

   for i = 1 to length(s) do
      t = s[i]
      for k = 1 to 2 do
         if and_bits(t, #FFFF) = val then
            return (i-1)*2 + k
         end if
         t = c_func( SHIFT_RIGHT, {t, 16} )
      end for
   end for

   return 0                       -- val not found
end function

global function find_short_reverse (short val, sequence_of_long s)
   -- Return the number of the highest order short integer in 's', that is equal
   -- to 'val' (or return -1, if 'val' is not found).
   -- It doesn't matter, whether 'val' is signed or unsigned.
   atom t

   if val < 0 then
      val += #10000               -- convert to unsigned
   end if

   for i = length(s) to 1 by -1 do
      t = s[i]
      for k = 2 to 1 by -1 do
         t = c_func( ROTATE_LEFT, {t, 16} )
         if and_bits(t, #FFFF) = val then
            return (i-1)*2 + k
         end if
      end for
   end for

   return 0                       -- val not found
end function

------------------------------------------------------------------------

-- * Demo * --
object s
sequence_of_long pattern
sequence p
positive_int numShortInts
integer fn
short val

fn = open("short.txt", "w")
numShortInts = 6

pattern = new_short(numShortInts)
p = "0"
for i = 1 to ceil(numShortInts/2)-1 do
   p &= ",0"
end for

without warning                        -- no short-circuite warning, please

for no = 1 to numShortInts + 1 do
   val = rand(65536+32768)-32769       -- signed or unsigned short integer
   s = put_short(pattern, no, val)     --                  [-#8000, #FFFF]
   printf(fn, "s = put_short({%s}, %d, #%04x)", {p, no, and_bits(val, #FFFF)})
   puts(fn, "\n-> s = ")
   if sequence(s) then
      pretty_print(fn, s, {0,3,1,78,"#%08x","#%08x"})
      if val <  0 and val != get_short_s(s, no) then
         puts(fn, "* Error *\n")
         printf(fn, "  val           = #%04x\n", {val})
         printf(fn, "  get_short_s() = #%04x\n", {get_short_s(s, no)})
      elsif val >= 0 and val != get_short_u(s, no) then
         puts(fn, "* Error *\n")
         printf(fn, "  val           = #%04x\n", {val})
         printf(fn, "  get_short_u() = #%04x\n", {get_short_u(s, no)})
      end if
      printf(fn, "-> find_short_forward(#%04x, s) = %d\n",
                     {and_bits(val, #FFFF), find_short_forward(val, s)})
      printf(fn, "-> find_short_reverse(#%04x, s) = %d\n",
                     {and_bits(val, #FFFF), find_short_reverse(val, s)})
   else
      printf(fn, "%d\n", {s})
   end if
   puts(fn, "\n")
end for

puts(fn, "---------------------------------------\n\n")

s = pack_short({-3,-2,-1,0,1,2,3})
pretty_print(fn, s, {0,3,1,78,"#%08x","#%08x"})
puts(fn, "\n")
pretty_print(fn, unpack_short_s(s), {})
pretty_print(fn, unpack_short_u(s), {})

close(fn)
puts(1, "finished\n")


Regards,
   Juergen

new topic     » goto parent     » topic index » view thread      » older message » newer message

Search



Quick Links

User menu

Not signed in.

Misc Menu