Skip to content

Commit d1a2360

Browse files
committed
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.
2 parents d0f88cd + d22f417 commit d1a2360

File tree

2 files changed

+41
-0
lines changed

2 files changed

+41
-0
lines changed

src/libstd/hash.rs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -558,4 +558,15 @@ mod tests {
558558
val & !(0xff << (byte * 8))
559559
}
560560
}
561+
562+
#[test]
563+
fn test_float_hashes_differ() {
564+
assert!(0.0.hash() != 1.0.hash());
565+
assert!(1.0.hash() != (-1.0).hash());
566+
}
567+
568+
#[test]
569+
fn test_float_hashes_of_zero() {
570+
assert_eq!(0.0.hash(), (-0.0).hash());
571+
}
561572
}

src/libstd/to_bytes.rs

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ The `ToBytes` and `IterBytes` traits
1414
1515
*/
1616

17+
use cast;
1718
use io;
1819
use io::Writer;
1920
use option::{None, Option, Some};
@@ -190,6 +191,35 @@ impl IterBytes for int {
190191
}
191192
}
192193

194+
impl IterBytes for float {
195+
#[inline(always)]
196+
fn iter_bytes(&self, lsb0: bool, f: Cb) -> bool {
197+
(*self as f64).iter_bytes(lsb0, f)
198+
}
199+
}
200+
201+
impl IterBytes for f32 {
202+
#[inline(always)]
203+
fn iter_bytes(&self, lsb0: bool, f: Cb) -> bool {
204+
let i: u32 = unsafe {
205+
// 0.0 == -0.0 so they should also have the same hashcode
206+
cast::transmute(if *self == -0.0 { 0.0 } else { *self })
207+
};
208+
i.iter_bytes(lsb0, f)
209+
}
210+
}
211+
212+
impl IterBytes for f64 {
213+
#[inline(always)]
214+
fn iter_bytes(&self, lsb0: bool, f: Cb) -> bool {
215+
let i: u64 = unsafe {
216+
// 0.0 == -0.0 so they should also have the same hashcode
217+
cast::transmute(if *self == -0.0 { 0.0 } else { *self })
218+
};
219+
i.iter_bytes(lsb0, f)
220+
}
221+
}
222+
193223
impl<'self,A:IterBytes> IterBytes for &'self [A] {
194224
#[inline(always)]
195225
fn iter_bytes(&self, lsb0: bool, f: Cb) -> bool {

0 commit comments

Comments
 (0)