numbits.sa
Generated by gen_html_sa_files from ICSI. Contact gomes@icsi.berkeley.edu for details
-------------------------> GNU Sather - sourcefile <-------------------------
-- Copyright (C) 2000 by K Hopper, University of Waikato, New Zealand --
-- This file is part of the GNU Sather library. It is free software; you may --
-- redistribute and/or modify it under the terms of the GNU Library General --
-- Public License (LGPL) as published by the Free Software Foundation; --
-- either version 2 of the license, or (at your option) any later version. --
-- This library is distributed in the hope that it will be useful, but --
-- WITHOUT ANY WARRANTY without even the implied warranty of MERCHANTABILITY --
-- or FITNESS FOR A PARTICULAR PURPOSE. See Doc/LGPL for more details. --
-- The license text is also available from: Free Software Foundation, Inc., --
-- 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA --
--------------> Please email comments to <bug-sather@gnu.org> <--------------
immutable class NUM_BITS < $BIT_PATTERN{NUM_BITS}
immutable class NUM_BITS < $BIT_PATTERN{NUM_BITS} is
-- This class is the immutable class which has an implementation defined
-- number of bits, being the number of bits used for exact arithmetic,
-- but otherwise may have any meaning. Only equality and bit operations
-- are specified.
-- This class is provided separately in order to permit compiler
-- optimisation of 'register'-sized (usually) testing and bit manipulation.
-- Version 1.0 Dec 96. Copyright K Hopper, U of Waikato
-- Development History
-- -------------------
-- Date Who By Detail
-- ---- ------ ------
-- 19 Dec 96 kh Original (for 32-bits)
-- NOTE The body of this class will either include one of OCTET,
-- HEXTET or QUADBITS dependent upon 'register' width, or if wider
-- registers are available then it should be separately written
-- following the pattern of those classes.
include QUADBITS -- This is a 32-bit version.
build -> ;
-- The following constants are provided as universals for use with
-- exact arithmetic classes, code classes, etc. They must be altered in
-- the light of the include class (or new body) in use.
const Num_Bits : CARD := QUADBITS::asize ;
const Num_Max : CARD := Quad_Max ;
const Octets_per_Card : CARD := Octets_per_Quad ;
const Big_Shift : CARD := 17 ; -- Shifts for hashing!
const Lesser_Shift : CARD := 15 ;
const Magic_Prime : CARD := 4292967291 ; -- largest prime!
create(
val : QUADBITS
) : SAME is
-- This produces a new object which takes the value val as a bit-pattern.
-- It relies on the size of quad and num bits.
builtin CARD_QUAD
end ;
build(
cursor : BIN_CURSOR
) : SAME
pre (cursor.remaining >= (asize / OCTET::Octet_Bits))
post initial(cursor.get_upto(asize / OCTET::Octet_Bits)) = result.binstr
is
-- This creates a new object and advances the cursor by the appropriate
-- number of octets.
return create(((cursor.get_item).quad.left(3 * OCTET::Octet_Bits)).bit_or(
(cursor.get_item).quad.left(2 * OCTET::Octet_Bits)).bit_or(
(cursor.get_item).quad.left(1 * OCTET::Octet_Bits)).bit_or(
(cursor.get_item).quad))
end ;
create(
val : INT
) : SAME is
-- This produces a new object which takes the value val as a bit-pattern.
-- It relies on the built-in conversion INT_NUM operation.
--
-- NOTE This routine is required in order to be able to produce octal, etc
-- character string representations of an integer.
builtin INT_NUM
end ;
-- NOTE The following two routines are included in order to be able to
-- produce a hash function for approximate numbers based upon their
-- bit-patterns rather than any numeric conversions. Either one
-- or both may generate run-time code.
create(
val : FLT
) : SAME is
-- This produces a new object which takes the value val as a bit-pattern.
-- It relies on the built-in conversion FLT_NUM operation.
builtin FLT_NUM
end ;
create(
val : FLTD
) : SAME is
-- This produces a new object which takes the value val as a bit-pattern.
-- It relies on the built-in conversion FLTD_NUM operation.
builtin FLTD_NUM
end ;
quad : QUADBITS
pre true
post self.bit_and(create(QUADBITS::Quad_Max)).card = result.card
is
-- This routine returns a copy of self. This is included here for
-- symmetry with the general bit-pattern classes for the case when num-bits
-- is a 64-bit bit-pattern.
return QUADBITS::create(card)
end ;
hash : CARD is
-- This routine returns a hash value computed from self by successive
-- shifts and xors of the bit-pattern forming the numeric value. It is
-- important to separate adjacent numeric values, even if there is no
-- collision. For example, if SYS::id returns objects in consecutive aligned
-- positions, the result should not be successive values. Unfortunately,
-- it is not good enough to just multiply/add by soe magic numbers, since
-- that doesn't affect the randomness once passed through a mod function
-- (for instance FSET etc. just use the rightmost bits, equivalent to mod by
-- a power of two.) This implementation therefore does a few steps of
-- a shift generator.
bits : SAME ;
if card = 0 then
bits := create(Magic_Prime)
else
bits := self.bit_xor(self.left(Big_Shift))
end ;
bits := bits.bit_xor(bits.right(Lesser_Shift)) ;
bits := bits.bit_xor(bits.left(Big_Shift)) ;
bits := bits.bit_xor(bits.right(Lesser_Shift)) ;
bits := bits.bit_xor(bits.left(Big_Shift)) ;
bits := bits.bit_xor(bits.right(Lesser_Shift)) ;
return bits.card
end ;
convolve(
other : SAME
) : SAME is
-- This routine carries out a convolution of self and other, returning
-- the result. This is provided where hashing needs to involve two or more
-- attributes of some class.
bits : SAME := self.bit_xor(other.left(Big_Shift)) ;
loc_bits : SAME := other.bit_xor(bits.right(Lesser_Shift)) ;
bits := bits.bit_xor(bits.left(Big_Shift)) ;
bits := bits.bit_xor(bits.right(Lesser_Shift)) ;
if bits.lowest > 0 then -- make LSB set!
bits := bits.right(lowest)
end ;
return bits
end ;
end ; -- NUM_BITS