3 ms·
No you don’t, you want to use the hardware defined equality function. And that one is IEEE 754 compliant.
by moomin 4y ago
No you don’t, you want to use the hardware defined equality function. And that one is IEEE 754 compliant.
- anonymoushn 4y agoHow are you so sure what other people want? Using the hardware defined equality function for integers is reasonable a lot of the time.
- duped 4y agoMy point is sometimes I want NaN to compare with NaN as true when I'm using a float as a key in a table.
- tialaramex 4y agoYou are welcome to build a type which has this property and declares that it is Eq. But Rust's built-in floating point types f32 and 64 do not have that property.
- jeroenhd 4y agoIn a hash table, I want my equality function to be based on the actual value, not the super special comparison for a specific type. If I write a UniqueNumber that just returns false on the == operator, I'd be stupid but the hash map should still work. Java has a separate getHashCode() and equals() method for a reason. Either provide a hash key override or use the raw bits for deep compares. Custom equality algorithms usually don't make sense for arbitrary key-value stores.
- tialaramex 4y agoBecause of the Pigeonhole Principle what you're describing is nonsense. In Rust you can make UniqueNumber, indeed misfortunate::OnewayGreater is such a type. misfortunate::Maxwell even more so. However of course the HashMap can't meaningfully "work" for this type. Rust promises your program doesn't have Undefined Behaviour despite such a prank, but it might spin forever when you try to insert this type into a map for example, a well defined but undesirable behaviour brought on by your poor choices. You seem to imagine that Java's hash map doesn't need to compare types, that it can just use getHashCode() -- however because of the Pigeonhole Principle that can't actually work. And NaN != NaN isn't a "custom equality algorithm" it's literally how the floating point numbers are defined in your CPU.
- squeaky-clean 4y agoThe Java (openjdk) hashmap putValue doesn't seem to compare types, it just uses .equals() if (p.hash == hash && ((k = p.key) == key || (key != null && key.equals(k)))) You can't really rely on checking types in a Hashmap anyways because the type you're hashing can have more possible values than the 32bit hash. For example you can have 2 strings that have a hash collision. NaN's work in a Java hashmap because Float.hashCode returns floatToIntBits(float) which normalizes all NaN's to a canonical value.
- tialaramex 4y agoSorry, I should have said compare values of-this-type. I was focused on the fact that type does matter here, which as you show the equals method is called on key, not some arbitrary system-wide equals method but a method defined on key's type. Rust has a magic unstable trait StructuralEq which means not only are we promised that values of this type can be compared for equality (that's what Eq does) but that comparison will just be a bitwise memory comparison. Lots of useful things are not StructuralEq even if they are Eq Apparently Java's Floats also do the same canonicalisation for equals(). So in effect in Java although NaN != NaN, once you box it that ceases to be true. This seems like a spectacularly bad idea to me, but presumably it made somebody's awful hack work at one point.
- senknvd 4y ago> This seems like a spectacularly bad idea to me, but presumably it made somebody's awful hack work at one point. but elsewhere you say, "You are welcome to build a type which has this property and declares that it is Eq". This is exactly the difference between double and Double in Java. double has the `==` operator that isn't reflexive and works as required by IEEE-754 and Double has Double.equals, which is documented[1] to be a reflexive, transitive, symmetric, consistent, and substitutable relation. [1]: https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/lang/Object.html#equals(java.lang.Object) https://docs.oracle.com/en/java/javase/17/docs/api/java.base...
- 4y ago