From 7162bfed5778699e3365c13f3fbe93fe03efbb72 Mon Sep 17 00:00:00 2001 From: John Benediktsson <mrjbq7@gmail.com> Date: Sat, 16 Mar 2013 13:53:58 -0700 Subject: [PATCH] math.hashcodes: consistent number hashing. --- extra/math/hashcodes/hashcodes-tests.factor | 16 +++++++ extra/math/hashcodes/hashcodes.factor | 50 +++++++++++++++++++++ 2 files changed, 66 insertions(+) create mode 100644 extra/math/hashcodes/hashcodes-tests.factor create mode 100644 extra/math/hashcodes/hashcodes.factor diff --git a/extra/math/hashcodes/hashcodes-tests.factor b/extra/math/hashcodes/hashcodes-tests.factor new file mode 100644 index 0000000000..dee079617e --- /dev/null +++ b/extra/math/hashcodes/hashcodes-tests.factor @@ -0,0 +1,16 @@ +! Copyright (C) 2013 John Benediktsson +! See http://factorcode.org/license.txt for BSD license + +USING: kernel sequences tools.test ; + +IN: math.hashcodes + +{ t } [ + { 12 12.0 C{ 12 0 } } + [ number-hashcode 12 = ] all? +] unit-test + +{ t } [ + { 1.5 3/2 C{ 1.5 0 } C{ 3/2 0 } } + [ number-hashcode 3458764513820540928 = ] all? +] unit-test diff --git a/extra/math/hashcodes/hashcodes.factor b/extra/math/hashcodes/hashcodes.factor new file mode 100644 index 0000000000..42abe8cf85 --- /dev/null +++ b/extra/math/hashcodes/hashcodes.factor @@ -0,0 +1,50 @@ +! Copyright (C) 2013 John Benediktsson +! See http://factorcode.org/license.txt for BSD license + +USING: combinators kernel layouts math math.bitwise +math.floating-point math.functions ; + +IN: math.hashcodes + +GENERIC: number-hashcode ( x -- h ) + +<PRIVATE + +: P ( -- x ) + cell-bits 64 = 61 31 ? 2^ 1 - ; inline foldable + +: M ( -- x ) + cell-bits 1 - 2^ ; inline foldable + +: hash-fraction ( m n -- h ) + + [ 2dup [ P mod zero? ] bi@ and ] [ + [ P /i ] bi@ + ] while + + dup P mod zero? [ + 2drop 1/0. + ] [ + over [ + [ abs P mod ] [ P 2 - P ^mod P mod ] bi* * + ] dip 0 < [ neg ] when + dup -1 = [ drop -2 ] when + ] if ; inline + +PRIVATE> + +M: integer number-hashcode 1 hash-fraction ; + +M: ratio number-hashcode >fraction hash-fraction ; + +M: float number-hashcode ( x -- h ) + { + { [ dup fp-nan? ] [ drop 0 ] } + { [ dup fp-infinity? ] [ 0 > 314159 -314159 ? ] } + [ double>ratio number-hashcode ] + } cond ; + +M: complex number-hashcode ( x -- h ) + >rect [ number-hashcode ] bi@ 1000003 * + + [ M 1 - bitand ] [ M bitand ] bi - + dup -1 = [ drop -2 ] when ;