LargeInteger.st
branchjv
changeset 19559 d35a89d5c0ec
parent 19332 9686fae7951b
parent 19555 29a4c770f926
child 19611 b1aaf1175f51
--- a/LargeInteger.st	Sun Apr 03 07:04:52 2016 +0200
+++ b/LargeInteger.st	Fri Apr 08 07:02:36 2016 +0100
@@ -2200,31 +2200,30 @@
 hash
     "return an integer useful for hashing on large numbers"
 
-    |l h m|
-
-    h := self bitAnd:16r3FFFFFFF.
-
-    l := digitByteArray size.
-    l >= 8 ifTrue:[
-	h := h bitXor:(digitByteArray at:l).
-	h := h bitXor:((digitByteArray at:l-1) bitShift:8).
-	h := h bitXor:((digitByteArray at:l-2) bitShift:16).
-	h := h bitXor:((digitByteArray at:l-3) bitShift:22).
-	l >= 12 ifTrue:[
-	    m := l // 2.
-	    h := h bitXor:(digitByteArray at:m-1).
-	    h := h bitXor:((digitByteArray at:m) bitShift:8).
-	    h := h bitXor:((digitByteArray at:m+1) bitShift:16).
-	    h := h bitXor:((digitByteArray at:m+2) bitShift:22).
-	].
-	^ h
+    |sz h|
+
+    sz := digitByteArray size.
+    (sz <= SmallInteger maxBytes and:[self absLess:SmallInteger maxVal]) ifTrue:[
+        "I am really an unnormalized SmallInteger, answer the same hash as for the SmallInteger"
+        ^ self bitAnd:SmallInteger maxVal.
     ].
-    ^ (h bitShift:3) + l
+
+    h := digitByteArray computeXorHashFrom:1 to:8.                  "/ the low 8 bytes
+    sz > 8 ifTrue:[                                                 "/ the high 8 bytes
+        h := h bitXor:(digitByteArray computeXorHashFrom:sz-8 to:sz).
+    ].
+    ^ h
 
     "
      16r80000000 hash
+     16r-80000000 asLargeInteger hash
      16r80000008 hash
      16r8000000000008 hash
+
+     16r8000000000000000 hash
+     16r8000000000000008 hash
+     16r800000000000000000008 hash
+     16r-800000000000000000008 hash
     "
 !