Skip to content

Commit 69a31e0

Browse files
committed
Fix type instability in decompose(::Float64) on 32-bit
Need at least 64-bit to store the result of Float64 decomposition. (A very good use case for return type declarations.)
1 parent 366060d commit 69a31e0

File tree

1 file changed

+11
-11
lines changed

1 file changed

+11
-11
lines changed

base/hashing2.jl

+11-11
Original file line numberDiff line numberDiff line change
@@ -96,49 +96,49 @@ Special values:
9696
decompose(x::Integer) = x, 0, 1
9797
decompose(x::Rational) = num(x), 0, den(x)
9898

99-
function decompose(x::Float16)
99+
function decompose(x::Float16)::NTuple{3,Int}
100100
isnan(x) && return 0, 0, 0
101101
isinf(x) && return ifelse(x < 0, -1, 1), 0, 0
102102
n = reinterpret(UInt16, x)
103103
s = (n & 0x03ff) % Int16
104104
e = (n & 0x7c00 >> 10) % Int
105105
s |= Int16(e != 0) << 10
106106
d = ifelse(signbit(x), -1, 1)
107-
Int(s), Int(e - 25 + (e == 0)), d
107+
s, e - 25 + (e == 0), d
108108
end
109109

110-
function decompose(x::Float32)
110+
function decompose(x::Float32)::NTuple{3,Int}
111111
isnan(x) && return 0, 0, 0
112112
isinf(x) && return ifelse(x < 0, -1, 1), 0, 0
113113
n = reinterpret(UInt32, x)
114114
s = (n & 0x007fffff) % Int32
115115
e = (n & 0x7f800000 >> 23) % Int
116116
s |= Int32(e != 0) << 23
117117
d = ifelse(signbit(x), -1, 1)
118-
Int(s), Int(e - 150 + (e == 0)), d
118+
s, (e - 150 + (e == 0)), d
119119
end
120120

121-
function decompose(x::Float64)
121+
function decompose(x::Float64)::Tuple{Int64, Int, Int}
122122
isnan(x) && return 0, 0, 0
123123
isinf(x) && return ifelse(x < 0, -1, 1), 0, 0
124124
n = reinterpret(UInt64, x)
125125
s = (n & 0x000fffffffffffff) % Int64
126126
e = (n & 0x7ff0000000000000 >> 52) % Int
127127
s |= Int64(e != 0) << 52
128128
d = ifelse(signbit(x), -1, 1)
129-
s, Int(e - 1075 + (e == 0)), d
129+
s, e - 1075 + (e == 0), d
130130
end
131131

132-
function decompose(x::BigFloat)
133-
isnan(x) && return big(0), 0, 0
134-
isinf(x) && return big(x.sign), 0, 0
135-
x == 0 && return big(0), 0, Int(x.sign)
132+
function decompose(x::BigFloat)::Tuple{BigInt, Int, Int}
133+
isnan(x) && return 0, 0, 0
134+
isinf(x) && return x.sign, 0, 0
135+
x == 0 && return 0, 0, x.sign
136136
s = BigInt()
137137
s.size = cld(x.prec, 8*sizeof(GMP.Limb)) # limbs
138138
b = s.size * sizeof(GMP.Limb) # bytes
139139
ccall((:__gmpz_realloc2, :libgmp), Void, (Ptr{BigInt}, Culong), &s, 8b) # bits
140140
ccall(:memcpy, Ptr{Void}, (Ptr{Void}, Ptr{Void}, Csize_t), s.d, x.d, b) # bytes
141-
s, Int(x.exp - 8b), Int(x.sign)
141+
s, x.exp - 8b, x.sign
142142
end
143143

144144
## streamlined hashing for smallish rational types ##

0 commit comments

Comments
 (0)