[m-dev.] hash_float() (was pragma fact_table)

David Matthew OVERTON dmo at students.cs.mu.oz.au
Fri Feb 28 17:11:04 AEDT 1997


Hi,

Could someone please review this.

Estimated hours taken: 2

Prolog version of `float__hash'.

library/float.nu.nl
	Add a new predicate `float__hash'.  Note: this one computes a
	different hash value to the one in `float.m'.

cvs diff: Diffing .
Index: float.nu.nl
===================================================================
RCS file: /home/staff/zs/imp/mercury/library/float.nu.nl,v
retrieving revision 1.3
diff -u -r1.3 float.nu.nl
--- float.nu.nl	1996/11/24 14:25:39	1.3
+++ float.nu.nl	1997/02/28 06:02:39
@@ -49,4 +49,32 @@
 
 float__epsilon(2.2204460492503131e-16).
 
+	%  Note:  This hash function is different to the one defined in
+	%  float.m.
+	%  How it works:  first ensure Float is positive by taking the
+	%  absolute value (Abs) and then adding epsilon if Abs == 0.0
+	%  (Abs2).  Next calculate the lowest power of e that is >=
+	%  Abs2 (i.e.  exp(ceil(log(Abs2)))).  Divide Abs2 by this
+	%  number to get a number in the range exp(-1) to 1.  Multiply
+	%  this by 2^31-1 to get a number, Float2,  in the range
+	%  790015083 to 2147483647.  To include the magnitude of Float
+	%  in the computation, add ceil(log(Abs2)) to Float2 and then
+	%  truncate the result to an integer (N2).  Truncate Float2 to
+	%  integer (N1), XOR with N2 and take the absolute value to
+	%  ensure the result in non-negative.
+
+float__hash(Float, Hash) :-
+	( Float >= 0 -> Abs = Float ; Abs is -Float),
+	( Abs = 0.0 -> float__epsilon(Abs2) ; Abs2 = Abs ),
+	Log is log(Abs2),
+	R0 is round(Log),
+	( R0 < Log -> R is R + 1 ; R is R0),
+	Exp is exp(R),
+	Float2 is Abs2 / Exp * 2147483647.0,   % 2147483647 = (2^31)-1
+	N1 is integer(Float2),
+	( R >= 0 -> R1 = R ; R1 is -R),
+	N2 is integer(R1),
+	Hash0 is N1 ^ N2,
+	int__abs(Hash0, Hash).
+
 %-----------------------------------------------------------------------------%



More information about the developers mailing list