<< Back to previous view

[CLJ-1204] hash is inconsistent with = for many BigInteger values Created: 18/Apr/13  Updated: 05/Sep/13  Resolved: 05/Sep/13

Status: Closed
Project: Clojure
Component/s: None
Affects Version/s: Release 1.4, Release 1.5
Fix Version/s: None

Type: Defect Priority: Minor
Reporter: Andy Fingerhut Assignee: Unassigned
Resolution: Duplicate Votes: 0
Labels: None

Attachments: Text File clj-1204-make-hash-consistent-with-equal-for-bigintegers-v1.txt    
Patch: Code and Test

 Description   

The function hash is documented to be consistent with =. For many BigInteger values, hash is inconsistent with =. This leads to incorrect behavior for data structures like hash maps that use hash.

user> (apply = [-1 -1N (biginteger -1)])
true
user> (map hash [-1 -1N (biginteger -1)])
(0 0 -1)

;; Incorrect return value with multiple keys = to each other
user> (assoc (hash-map -1N :should-be-replaced) (biginteger -1) :new-val)
{-1N :should-be-replaced, -1 :new-val}

;; array-map gives correct value, since it uses =, not hash
user> (assoc (array-map -1N :should-be-replaced) (biginteger -1) :new-val)
{-1N :new-val}


 Comments   
Comment by Andy Fingerhut [ 18/Apr/13 8:10 PM ]

Patch clj-1204-make-hash-consistent-with-equal-for-bigintegers-v1.txt dated Apr 18 2013 takes the following approach to the issue:

Change the behavior of hasheq so that when given a BigInteger value that could fit into a long, returns the same hash code as that long value.

hasheq continues to return x.hashCode() if the BigInteger value does not fit into a long. This is consistent with the hash value returned by a BigInt value that does not fit into a long.

New tests are included, some of which fail without the change to hasheq, but pass with the change.

Comment by Andy Fingerhut [ 18/Apr/13 8:19 PM ]

Overwrite patch with one that leaves out some unnecessary code.

Comment by Andy Fingerhut [ 25/Apr/13 6:42 PM ]

Changing priority to minor, since I suppose one could work around this issue, if you were diligent about it, by converting all BigIntegers to BigInts before they are ever used in a place where they are hashed.

Comment by Andy Fingerhut [ 05/Sep/13 9:00 AM ]

with CLJ-1036, which is out of scope for Clojure, so this one should be as well.

Generated at Sat Oct 25 07:13:06 CDT 2014 using JIRA 4.4#649-r158309.