Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

java hashcode for floating point numbers

I want to use Double (or Float) as keys in a Hashmap

Map<Double, String> map = new HashMap<Double, String>()
map.put(1.0, "one");
System.out.println(map.containsKey(Math.tan(Math.PI / 4)));

and this returns false.

if I were comparing these two numbers I would have done something like this

final double EPSILON = 1e-6;
Math.abs(1.0 - Math.tan(Math.PI / 4)) < EPSILON

But since Hashmap would use hashcode it breaks things for me.

I thought to implement a roundKey function that rounds to some multiple of EPSILON before using it as a key

map.put(roundKey(1.0), "one")
map.containsKey(roundKey(Math.tan(Math.PI / 4)))
  • is there a better way ?
  • what is the right way to implement this roundKey
like image 200
mzzzzb Avatar asked Jun 14 '26 20:06

mzzzzb


1 Answers

If you know what rounding is appropriate, you can use that. e.g. if you need to round to cents, you can round to two decimal places.

However, for the example above discrete rounding to a fixed precision might not be appropriate. e.g. if you round to 6 decimal places, 1.4999e-6 and 1.5001e-6 will not match as one rounds up and the other down even though the difference is << 1e-6.

In that situation the closest you can do is to use a NavigableMap

NavigableMap<Double, String> map = new TreeMap<>();

double x = ....;
double error = 1e-6;

NavigableMap<Double, String> map2 = map.subMap(x - error, x + error);

or you can use

Map.Entry<Double, String> higher = map.higherEntry(x);
Map.Entry<Double, String> lower = map.lowerEntry(x);
Map.Entry<Double, String> entry = null;
if (higher == null)
    entry = lower;
else if (lower == null)
    entry = higher;
else if (Math.abs(lower.getKey() - x) < Math.abs(higher.getkey() - x))
    entry = lower;
else
    entry = higher;
// entry is the closest match.
if (entry != null && Math.abs(entry - x) < error) {
    // found the closest entry within the error
}

This will find all the entries within a continuous range.

like image 95
Peter Lawrey Avatar answered Jun 17 '26 10:06

Peter Lawrey



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!