Hash a double in Java
Solution 1
Double.hashCode()
complex? It basically converts double
into a long
(no magic here, after all they both are simply 64-bit values in memory) and computing long
hash is quite simple. The double
-> long
conversion is done via public static doubleToLongBits()
. What is complex about this?
Examples:
Double.valueOf(42.5).hashCode(); //better answer to everything
Long.valueOf(Double.doubleToLongBits(42.5)).hashCode();
Solution 2
The way Java does it is to convert the raw bit of a double into a long.
// from Double.
public static long doubleToLongBits(double value) {
long result = doubleToRawLongBits(value);
// Check for NaN based on values of bit fields, maximum
// exponent and nonzero significand.
if ( ((result & DoubleConsts.EXP_BIT_MASK) ==
DoubleConsts.EXP_BIT_MASK) &&
(result & DoubleConsts.SIGNIF_BIT_MASK) != 0L)
result = 0x7ff8000000000000L;
return result;
}
public int hashCode() {
long bits = doubleToLongBits(value);
return (int)(bits ^ (bits >>> 32));
}
Note: There many values of NaN (and two types) but Java treats them as all the same.
Solution 3
Depending on what you need this for, you could go with a very simple approach of just mod(ing) it.
int hash(double d) {
return d % 71; //use a prime number here
}
If it is just for storing a few doubles in a hash, this should do it. If you want to spread the hash, just increase the "71"
Solution 4
This one worked for me
int h2 = new Double(area).hashCode();
Related videos on Youtube
daveb
Updated on July 18, 2022Comments
-
daveb almost 2 years
I was wondering how to hash a double in Java? I have hashed other primitive data and objects. I thought I could use the hashcode method? From what I have seen this looks quite complex. I came across something about creating a seed.
I was wondering any ideas on how to go about this. Hoping to put in with the rest of my hashcode for the class that has the double?
I was wondering if there are issues with me trying to hash arraylists, arrays and other objects in java. Some of my classes contain arraylists.
Many Thanks
-
daveb about 12 yearsHi Tomasz, i tried the hashcode on the double and got the following message cannot be dereferenced. I am running hashcode() method on a getClassMethod() i.e this.getClassMethod().hashCode(); The getClassMethod returns the double.
-
Tomasz Nurkiewicz about 12 years@daveb: have a look at examples I just added to my answer.
-
daveb about 12 yearsThanks @Thomasz, I did int hash6 = Double.valueOf(this.getClassMethod()).hashCode(); and it compiled without the previous problem. Is the line of code okay to you? Cheers DaveB
-
Tomasz Nurkiewicz about 12 yearsThis is a poor hash, it will return the same value for doubles close to each other. And what if your program only needs doubles between 0 and 1? Constant hash.
-
daveb about 12 yearsI am hashing up all the fields of the diff classes, and overriding hashcode, equals and to string for all my classes. So that I can compare objects from them and also make sure that objects are unique as well. I have been using 31 prime number and concatenating the hashcodes into 1. My double is for a price of an item. DaveB
-
krico about 12 years@TomaszNurkiewicz totally agree! That's why I started with "depending on what you need this for". If you "knew" your values were all between 0 and 1 you should use something else.
-
fishinear almost 11 years-1 this is an extremely poor hash function. It removes the fractional part completely. And in addition, it maps all numbers onto only 71 different ones.
-
krico over 10 years@fishinear, if you read my comment above yours, I agree with you.
-
Phil almost 6 yearsThe short answer is "don't hash doubles (or floats)". Hashing floating point numbers will not give you reasonable results because of the limits of precision. For instance [
a = 1d/3d;
] followed by [b = (a * 2 + 1) / 2 - 0.5d;
] will give you different answers as doubles, even though in a perfect world they would be the same. -
ToniAz about 5 years@Phil I second that. Folks hitting this page will see the answer above and take it as a solution where in fact it would break in practice.