Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WIP: preserve signs for +/-/*/... between IntXX and UIntYY #22482

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion base/combinatorics.jl
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ end
const _fact_table128 = Vector{UInt128}(34)
_fact_table128[1] = 1
for n in 2:34
_fact_table128[n] = _fact_table128[n-1] * n
_fact_table128[n] = _fact_table128[n-1] * UInt128(n)
end

function factorial_lookup(n::Integer, table, lim)
Expand Down
14 changes: 7 additions & 7 deletions base/float.jl
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ function convert(::Type{Float64}, x::UInt128)
y = ((x % UInt64) << (53-n)) & 0x000f_ffff_ffff_ffff
else
y = ((x >> (n-54)) % UInt64) & 0x001f_ffff_ffff_ffff # keep 1 extra bit
y = (y+1)>>1 # round, ties up (extra leading bit in case of next exponent)
y = (y+0x01)>>1 # round, ties up (extra leading bit in case of next exponent)
y &= ~UInt64(trailing_zeros(x) == (n-54)) # fix last bit to round to even
end
d = ((n+1022) % UInt64) << 52
Expand All @@ -95,7 +95,7 @@ function convert(::Type{Float64}, x::Int128)
y = ((x % UInt64) << (53-n)) & 0x000f_ffff_ffff_ffff
else
y = ((x >> (n-54)) % UInt64) & 0x001f_ffff_ffff_ffff # keep 1 extra bit
y = (y+1)>>1 # round, ties up (extra leading bit in case of next exponent)
y = (y+0x01)>>1 # round, ties up (extra leading bit in case of next exponent)
y &= ~UInt64(trailing_zeros(x) == (n-54)) # fix last bit to round to even
end
d = ((n+1022) % UInt64) << 52
Expand Down Expand Up @@ -134,7 +134,7 @@ end

function convert(::Type{Float16}, val::Float32)
f = reinterpret(UInt32, val)
i = (f >> 23) & 0x1ff + 1
i = (f >> 23) & 0x1ff + 0x01
sh = shifttable[i]
f &= 0x007fffff
h::UInt16 = basetable[i] + (f >> sh)
Expand All @@ -145,7 +145,7 @@ function convert(::Type{Float16}, val::Float32)
if nextbit != 0
# Round halfway to even or check lower bits
if h&1 == 1 || (f & ((1<<(sh-1))-1)) != 0
h += 1
h += 0x01
end
end
reinterpret(Float16, h)
Expand All @@ -158,7 +158,7 @@ function convert(::Type{Float32}, val::Float16)
local sig::UInt32 = (ival & 0x3ff) >> 0
local ret::UInt32

if exp == 0
if exp == 0x00
if sig == 0
sign = sign << 31
ret = sign | exp | sig
Expand Down Expand Up @@ -186,7 +186,7 @@ function convert(::Type{Float32}, val::Float16)
end
else
sign = sign << 31
exp = (exp - 15 + 127) << 23
exp = (exp + 0x70) << 23
sig = sig << (23 - 10)
ret = sign | exp | sig
end
Expand Down Expand Up @@ -550,7 +550,7 @@ isinf(x::Real) = !isnan(x) & !isfinite(x)

## hashing small, built-in numeric types ##

hx(a::UInt64, b::Float64, h::UInt) = hash_uint64((3a + reinterpret(UInt64,b)) - h)
hx(a::UInt64, b::Float64, h::UInt) = hash_uint64((0x03a + reinterpret(UInt64,b)) - h)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

0x03 * a ?

const hx_NaN = hx(UInt64(0), NaN, UInt(0 ))

hash(x::UInt64, h::UInt) = hx(x, Float64(x), h)
Expand Down
4 changes: 2 additions & 2 deletions base/hashing.jl
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ hash(w::WeakRef, h::UInt) = hash(w.value, h)

## hashing general objects ##

hash(x::ANY, h::UInt) = hash_uint(3h - object_id(x))
hash(x::ANY, h::UInt) = hash_uint(0x3h - object_id(x))

## core data hashing functions ##

Expand All @@ -27,7 +27,7 @@ function hash_64_32(n::UInt64)
local a::UInt64 = n
a = ~a + a << 18
a = a ⊻ a >> 31
a = a * 21
a = a * 0x15
a = a ⊻ a >> 11
a = a + a << 6
a = a ⊻ a >> 22
Expand Down
20 changes: 17 additions & 3 deletions base/int.jl
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ const BitSigned_types = (BitSigned64_types..., Int128)
const BitUnsigned_types = (BitUnsigned64_types..., UInt128)
const BitInteger_types = (BitSigned_types..., BitUnsigned_types...)

const BitSigned32 = Union{Int8,Int16,Int32}
const BitUnsigned32 = Union{UInt8,UInt16,UInt32}
const BitSigned64 = Union{BitSigned64_types...}
const BitUnsigned64 = Union{BitUnsigned64_types...}
const BitInteger64 = Union{BitInteger64_types...}
Expand Down Expand Up @@ -438,15 +440,15 @@ promote_rule(::Type{Int8}, ::Type{Int16}) = Int16
promote_rule(::Type{UInt8}, ::Type{UInt16}) = UInt16
promote_rule(::Type{Int32}, ::Type{<:Union{Int8,Int16}}) = Int32
promote_rule(::Type{UInt32}, ::Type{<:Union{UInt8,UInt16}}) = UInt32
promote_rule(::Type{Int64}, ::Type{<:Union{Int8,Int16,Int32}}) = Int64
promote_rule(::Type{UInt64}, ::Type{<:Union{UInt8,UInt16,UInt32}}) = UInt64
promote_rule(::Type{Int64}, ::Type{<:BitSigned32}) = Int64
promote_rule(::Type{UInt64}, ::Type{<:BitUnsigned32}) = UInt64
promote_rule(::Type{Int128}, ::Type{<:BitSigned64}) = Int128
promote_rule(::Type{UInt128}, ::Type{<:BitUnsigned64}) = UInt128
for T in BitSigned_types
@eval promote_rule(::Type{<:Union{UInt8,UInt16}}, ::Type{$T}) =
$(sizeof(T) < sizeof(Int) ? Int : T)
end
@eval promote_rule(::Type{UInt32}, ::Type{<:Union{Int8,Int16,Int32}}) =
@eval promote_rule(::Type{UInt32}, ::Type{<:BitSigned32}) =
$(Core.sizeof(Int) == 8 ? Int : UInt)
promote_rule(::Type{UInt32}, ::Type{Int64}) = Int64
promote_rule(::Type{UInt64}, ::Type{<:BitSigned64}) = UInt64
Expand Down Expand Up @@ -579,3 +581,15 @@ else
rem(x::Int128, y::Int128) = checked_srem_int(x, y)
rem(x::UInt128, y::UInt128) = checked_urem_int(x, y)
end

# operations where we want to preserve sign (#9292) for unsigned ⋆ signed:
for op in (:*, :+, :-, :div, :rem, :mod, ://)
@eval $op(x::UInt64, y::BitSigned64) = $op(Int64(x), y)
@eval $op(x::BitSigned64, y::UInt64) = $op(x, Int64(y))
@eval $op(x::UInt128, y::BitSigned) = $op(Int128(x), y)
@eval $op(x::BitSigned, y::UInt128) = $op(x, Int128(y))
if Core.sizeof(Int) == 4
@eval $op(x::UInt32, y::BitSigned32) = $op(Int32(x), y)
@eval $op(x::BitSigned32, y::UInt32) = $op(x, Int32(y))
end
end
2 changes: 1 addition & 1 deletion base/nofloat_hashing.jl
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
## hashing small, built-in numeric types
## for a system image built without floating point support

hx(a::UInt64, b::UInt64, h::UInt) = hash_uint64(3a + b - h)
hx(a::UInt64, b::UInt64, h::UInt) = hash_uint64(0x03a + b - h)

hash(x::UInt64, h::UInt) = hx(x, x, h)
hash(x::Int64, h::UInt) = hx(reinterpret(UInt64,abs(x)), reinterpret(UInt64,x), h)
Expand Down
4 changes: 2 additions & 2 deletions base/parse.jl
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ function tryparse_internal(::Type{T}, s::AbstractString, startpos::Int, endpos::
end

base = convert(T,base)
m::T = div(typemax(T)-base+1,base)
m::T = div(typemax(T)-base+0x01,base)
n::T = 0
a::Int = base <= 36 ? 10 : 36
while n <= m
Expand All @@ -92,7 +92,7 @@ function tryparse_internal(::Type{T}, s::AbstractString, startpos::Int, endpos::
n *= base
n += d
if i > endpos
n *= sgn
(T <: Signed) && (n *= sgn)
return Nullable{T}(n)
end
c, i = next(s,i)
Expand Down
8 changes: 4 additions & 4 deletions base/regex.jl
Original file line number Diff line number Diff line change
Expand Up @@ -163,11 +163,11 @@ function match(re::Regex, str::Union{SubString{String}, String}, idx::Integer, a
end
ovec = re.ovec
n = div(length(ovec),2) - 1
mat = SubString(str, ovec[1]+1, ovec[2])
mat = SubString(str, ovec[1]+0x01, ovec[2])
cap = Union{Void,SubString{String}}[
ovec[2i+1] == PCRE.UNSET ? nothing : SubString(str, ovec[2i+1]+1, ovec[2i+2]) for i=1:n ]
off = Int[ ovec[2i+1]+1 for i=1:n ]
RegexMatch(mat, cap, ovec[1]+1, off, re)
ovec[2i+1] == PCRE.UNSET ? nothing : SubString(str, ovec[2i+1]+0x01, ovec[2i+2]) for i=1:n ]
off = Int[ ovec[2i+1]+0x01 for i=1:n ]
RegexMatch(mat, cap, ovec[1]+0x01, off, re)
end

match(r::Regex, s::AbstractString) = match(r, s, start(s))
Expand Down