(value: f64)
| 90 | |
| 91 | #[inline] |
| 92 | pub fn hash_float(value: f64) -> Option<PyHash> { |
| 93 | // cpython _Py_HashDouble |
| 94 | if !value.is_finite() { |
| 95 | return if value.is_infinite() { |
| 96 | Some(if value > 0.0 { INF } else { -INF }) |
| 97 | } else { |
| 98 | None |
| 99 | }; |
| 100 | } |
| 101 | |
| 102 | let frexp = super::float_ops::decompose_float(value); |
| 103 | |
| 104 | // process 28 bits at a time; this should work well both for binary |
| 105 | // and hexadecimal floating point. |
| 106 | let mut m = frexp.0; |
| 107 | let mut e = frexp.1; |
| 108 | let mut x: PyUHash = 0; |
| 109 | while m != 0.0 { |
| 110 | x = ((x << 28) & MODULUS) | (x >> (BITS - 28)); |
| 111 | m *= 268_435_456.0; // 2**28 |
| 112 | e -= 28; |
| 113 | let y = m as PyUHash; // pull out integer part |
| 114 | m -= y as f64; |
| 115 | x += y; |
| 116 | if x >= MODULUS { |
| 117 | x -= MODULUS; |
| 118 | } |
| 119 | } |
| 120 | |
| 121 | // adjust for the exponent; first reduce it modulo BITS |
| 122 | const BITS32: i32 = BITS as i32; |
| 123 | e = if e >= 0 { |
| 124 | e % BITS32 |
| 125 | } else { |
| 126 | BITS32 - 1 - ((-1 - e) % BITS32) |
| 127 | }; |
| 128 | x = ((x << e) & MODULUS) | (x >> (BITS32 - e)); |
| 129 | |
| 130 | Some(fix_sentinel(x as PyHash * value.signum() as PyHash)) |
| 131 | } |
| 132 | |
| 133 | pub fn hash_bigint(value: &BigInt) -> PyHash { |
| 134 | let ret = match value.to_i64() { |
no test coverage detected