Clojure

hash is inconsistent with = for many BigInteger values

Details

  • Type: Defect Defect
  • Status: Closed Closed
  • Priority: Minor Minor
  • Resolution: Duplicate
  • Affects Version/s: Release 1.4, Release 1.5
  • Fix Version/s: None
  • Component/s: None
  • Labels:
    None
  • 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}

Activity

Hide
Andy Fingerhut added a comment -

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

Show
Andy Fingerhut added a comment - with CLJ-1036, which is out of scope for Clojure, so this one should be as well.
Hide
Andy Fingerhut added a comment -

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.

Show
Andy Fingerhut added a comment - 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.
Hide
Andy Fingerhut added a comment -

Overwrite patch with one that leaves out some unnecessary code.

Show
Andy Fingerhut added a comment - Overwrite patch with one that leaves out some unnecessary code.
Hide
Andy Fingerhut added a comment -

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.

Show
Andy Fingerhut added a comment - 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.

People

Vote (0)
Watch (1)

Dates

  • Created:
    Updated:
    Resolved: