Re: boolean sequence
- Posted by "Juergen Luethje" <j.lue at gmx.de> Sep 10, 2004
- 459 views
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. > 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