diff options
| author | bors <bors@rust-lang.org> | 2013-06-16 03:43:03 -0700 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2013-06-16 03:43:03 -0700 |
| commit | d1a2360b36fc43b818877d80a1bc8fd907032d00 (patch) | |
| tree | e59a23e6f8cd4eb19856a0c172f2ec387c694b6d | |
| parent | d0f88cd54e56f69f2b1ad46047d3a8d6aa43d13a (diff) | |
| parent | d22f417c74bf23c5a9c34d10ef5a327d2ab6ebab (diff) | |
| download | rust-d1a2360b36fc43b818877d80a1bc8fd907032d00.tar.gz rust-d1a2360b36fc43b818877d80a1bc8fd907032d00.zip | |
auto merge of #7156 : Dretch/rust/float-hash, r=graydon
It can sometimes be useful to have maps/sets of floating point values. Doing arithmetic with floats and then using them as keys is, of course, not a good idea.
| -rw-r--r-- | src/libstd/hash.rs | 11 | ||||
| -rw-r--r-- | src/libstd/to_bytes.rs | 30 |
2 files changed, 41 insertions, 0 deletions
diff --git a/src/libstd/hash.rs b/src/libstd/hash.rs index e9022445786..2d33be03580 100644 --- a/src/libstd/hash.rs +++ b/src/libstd/hash.rs @@ -558,4 +558,15 @@ mod tests { val & !(0xff << (byte * 8)) } } + + #[test] + fn test_float_hashes_differ() { + assert!(0.0.hash() != 1.0.hash()); + assert!(1.0.hash() != (-1.0).hash()); + } + + #[test] + fn test_float_hashes_of_zero() { + assert_eq!(0.0.hash(), (-0.0).hash()); + } } diff --git a/src/libstd/to_bytes.rs b/src/libstd/to_bytes.rs index c0c8b729f9e..6d7820ffea5 100644 --- a/src/libstd/to_bytes.rs +++ b/src/libstd/to_bytes.rs @@ -14,6 +14,7 @@ The `ToBytes` and `IterBytes` traits */ +use cast; use io; use io::Writer; use option::{None, Option, Some}; @@ -190,6 +191,35 @@ impl IterBytes for int { } } +impl IterBytes for float { + #[inline(always)] + fn iter_bytes(&self, lsb0: bool, f: Cb) -> bool { + (*self as f64).iter_bytes(lsb0, f) + } +} + +impl IterBytes for f32 { + #[inline(always)] + fn iter_bytes(&self, lsb0: bool, f: Cb) -> bool { + let i: u32 = unsafe { + // 0.0 == -0.0 so they should also have the same hashcode + cast::transmute(if *self == -0.0 { 0.0 } else { *self }) + }; + i.iter_bytes(lsb0, f) + } +} + +impl IterBytes for f64 { + #[inline(always)] + fn iter_bytes(&self, lsb0: bool, f: Cb) -> bool { + let i: u64 = unsafe { + // 0.0 == -0.0 so they should also have the same hashcode + cast::transmute(if *self == -0.0 { 0.0 } else { *self }) + }; + i.iter_bytes(lsb0, f) + } +} + impl<'self,A:IterBytes> IterBytes for &'self [A] { #[inline(always)] fn iter_bytes(&self, lsb0: bool, f: Cb) -> bool { |
