commons-issues mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Christopher Sahnwaldt (JIRA)" <j...@apache.org>
Subject [jira] Commented: (LANG-342) HashCodeBuilder.append(long) is incorrect
Date Wed, 19 Sep 2007 21:30:13 GMT

    [ https://issues.apache.org/jira/browse/LANG-342?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel#action_12528909
] 

Christopher Sahnwaldt commented on LANG-342:
--------------------------------------------

It doesn't matter if >>> or >> is used. We shift down the upper half of the
long and XOR with the lower half. Of course, we also XOR the unshifted upper half with the
shifted upper half (which consists of zeros or ones), but then we cast to int, which simply
throws away the upper half. It doesn't matter at all if there were zeros or ones in the shifted
upper half.

Here's a little test. Looping through all longs takes too long, let's just use random numbers.

java.util.Random rnd = new java.util.Random();
for (;;)
{
  long value = rnd.nextLong();
  int signed = (int)(value ^ (value >> 32));
  int unsigned = (int)(value ^ (value >>> 32));
  if (signed != unsigned) System.out.println(value+" "+signed+" "+unsigned);
}


> HashCodeBuilder.append(long) is incorrect
> -----------------------------------------
>
>                 Key: LANG-342
>                 URL: https://issues.apache.org/jira/browse/LANG-342
>             Project: Commons Lang
>          Issue Type: Bug
>            Reporter: Benjamin Manes
>            Priority: Minor
>             Fix For: 3.0
>
>
> I was looking at using HashCodeBuilder rather than always writing out the strategy by
hand, and I noticed one potential mistake:
>     /**
>      * Append a hashCode for a long.
>      *
>      * @param value  the long to add to the hashCode
>      * @return this
>      */
>     public HashCodeBuilder append(long value)
>     {
>         iTotal = iTotal * iConstant + ((int) (value ^ (value >> 32))); 
>         return this;
>     }
>  
> whereas Effective Java and Long.hashCode() use:
>     /**
>      * Returns a hash code for this <code>Long</code>. The result is
>      * the exclusive OR of the two halves of the primitive
>      * <code>long</code> value held by this <code>Long</code>

>      * object. That is, the hashcode is the value of the expression:
>      * <blockquote><pre>
>      * (int)(this.longValue()^(this.longValue()&gt;&gt;&gt;32))
>      * </pre></blockquote> 
>      *
>      * @return  a hash code value for this object.
>      */
>     public int hashCode() {
>       return (int)(value ^ (value >>> 32));
>     }
> So the author accidentally used a signed right-shift rather than an unsigned.
> ----
> Stephen Colebourne noted that while this is a bug, it is minor and could have backward
compatability issues.  I would simply recommend that a non-JavaDoc comment be added noting
this method doesn't follow "Effective Java" correctly.

-- 
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.


Mime
View raw message