[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