Skip to content

Commit

Permalink
make signed() and unsigned() unchecked. check only in convert()
Browse files Browse the repository at this point in the history
a few fixes in base for the convert and arithmetic changes

get all tests passing
  • Loading branch information
JeffBezanson committed Sep 25, 2014
1 parent 50f1d10 commit 16c2330
Show file tree
Hide file tree
Showing 8 changed files with 82 additions and 85 deletions.
4 changes: 2 additions & 2 deletions base/char.jl
Expand Up @@ -10,9 +10,9 @@ convert(::Type{Char}, x::Float64) = char(convert(Uint32, x))
## char promotions ##

promote_rule(::Type{Char}, ::Type{Int8}) = Int32
promote_rule(::Type{Char}, ::Type{Uint8}) = Int32
promote_rule(::Type{Char}, ::Type{Uint8}) = Uint32
promote_rule(::Type{Char}, ::Type{Int16}) = Int32
promote_rule(::Type{Char}, ::Type{Uint16}) = Int32
promote_rule(::Type{Char}, ::Type{Uint16}) = Uint32
promote_rule(::Type{Char}, ::Type{Int32}) = Int32
promote_rule(::Type{Char}, ::Type{Uint32}) = Uint32
promote_rule(::Type{Char}, ::Type{Int64}) = Int64
Expand Down
2 changes: 1 addition & 1 deletion base/datafmt.jl
Expand Up @@ -338,7 +338,7 @@ function dlm_parse{T,D}(dbuff::T, eol::D, dlm::D, qchar::D, cchar::D, ign_adj_dl
all_ascii = (D <: Uint8) || (isascii(eol) && isascii(dlm) && (!allow_quote || isascii(qchar)) && (!allow_comments || isascii(cchar)))
(T <: UTF8String) && all_ascii && (return dlm_parse(dbuff.data, uint8(eol), uint8(dlm), uint8(qchar), uint8(cchar), ign_adj_dlm, allow_quote, allow_comments, skipstart, skipblanks, dh))
ncols = nrows = col = 0
is_default_dlm = (dlm == convert(D, invalid_dlm))
is_default_dlm = (dlm == itrunc(D, invalid_dlm))
error_str = ""
# 0: begin field, 1: quoted field, 2: unquoted field, 3: second quote (could either be end of field or escape character), 4: comment, 5: skipstart
state = (skipstart > 0) ? 5 : 0
Expand Down
6 changes: 3 additions & 3 deletions base/grisu/fastfixed.jl
Expand Up @@ -110,8 +110,8 @@ function fillfractionals(fractionals, exponent,
return len, decimal_point
end

low(x) = uint64(x)
high(x) = uint64(x >> 64)
low(x) = uint64(x&0xffffffffffffffff)
high(x) = uint64(x >>> 64)
bitat(x::Uint128,y) = y >= 64 ? (int32(high(x) >> (y-64)) & 1) : (int32(low(x) >> y) & 1)
function divrem2(x,power)
h = high(x)
Expand Down Expand Up @@ -219,4 +219,4 @@ function fastfixedtoa(v,mode,fractional_count,buffer)
decimal_point = -fractional_count
end
return true, len, decimal_point, buffer
end
end
48 changes: 25 additions & 23 deletions base/int.jl
Expand Up @@ -43,23 +43,23 @@ abs(x::Signed) = flipsign(x,x)

~(n::Integer) = -n-1

asunsigned(x::Integer) = reinterpret(typeof(unsigned(zero(x))), x)
asunsigned(x::Bool) = unsigned(x)
asunsigned(x) = unsigned(x)
assigned(x::Integer) = reinterpret(typeof(signed(zero(x))), x)
assigned(x) = signed(x)
unsigned(x::Signed) = reinterpret(typeof(convert(Unsigned,zero(x))), x)
unsigned(x::Bool) = convert(Unsigned, x)
unsigned(x) = convert(Unsigned, x)
signed(x::Unsigned) = reinterpret(typeof(convert(Signed,zero(x))), x)
signed(x) = convert(Signed, x)

div(x::Signed, y::Unsigned) = flipsign(assigned(div(asunsigned(abs(x)),y)),x)
div(x::Unsigned, y::Signed) = asunsigned(flipsign(assigned(div(x,asunsigned(abs(y)))),y))
div(x::Signed, y::Unsigned) = flipsign(signed(div(unsigned(abs(x)),y)),x)
div(x::Unsigned, y::Signed) = unsigned(flipsign(signed(div(x,unsigned(abs(y)))),y))

rem(x::Signed, y::Unsigned) = flipsign(assigned(rem(asunsigned(abs(x)),y)),x)
rem(x::Unsigned, y::Signed) = rem(x,asunsigned(abs(y)))
rem(x::Signed, y::Unsigned) = flipsign(signed(rem(unsigned(abs(x)),y)),x)
rem(x::Unsigned, y::Signed) = rem(x,unsigned(abs(y)))

fld(x::Signed, y::Unsigned) = div(x,y)-(signbit(x)&(rem(x,y)!=0))
fld(x::Unsigned, y::Signed) = div(x,y)-(signbit(y)&(rem(x,y)!=0))

mod(x::Signed, y::Unsigned) = rem(y+asunsigned(rem(x,y)),y)
mod(x::Unsigned, y::Signed) = rem(y+assigned(rem(x,y)),y)
mod(x::Signed, y::Unsigned) = rem(y+unsigned(rem(x,y)),y)
mod(x::Unsigned, y::Signed) = rem(y+signed(rem(x,y)),y)

cld(x::Signed, y::Unsigned) = div(x,y)+(!signbit(x)&(rem(x,y)!=0))
cld(x::Unsigned, y::Signed) = div(x,y)+(!signbit(y)&(rem(x,y)!=0))
Expand Down Expand Up @@ -138,12 +138,12 @@ for T in IntTypes
end
end

==(x::Signed, y::Unsigned) = (x >= 0) & (asunsigned(x) == y)
==(x::Unsigned, y::Signed ) = (y >= 0) & (x == asunsigned(y))
< (x::Signed, y::Unsigned) = (x < 0) | (asunsigned(x) < y)
< (x::Unsigned, y::Signed ) = (y > 0) & (x < asunsigned(y))
<=(x::Signed, y::Unsigned) = (x <= 0) | (asunsigned(x) <= y)
<=(x::Unsigned, y::Signed ) = (y >= 0) & (x <= asunsigned(y))
==(x::Signed, y::Unsigned) = (x >= 0) & (unsigned(x) == y)
==(x::Unsigned, y::Signed ) = (y >= 0) & (x == unsigned(y))
< (x::Signed, y::Unsigned) = (x < 0) | (unsigned(x) < y)
< (x::Unsigned, y::Signed ) = (y > 0) & (x < unsigned(y))
<=(x::Signed, y::Unsigned) = (x <= 0) | (unsigned(x) <= y)
<=(x::Unsigned, y::Signed ) = (y >= 0) & (x <= unsigned(y))

## integer conversions ##

Expand All @@ -165,12 +165,16 @@ for to in tuple(IntTypes...,Char), from in tuple(IntTypes...,Char,Bool)
elseif !(issubtype(from,Signed) === issubtype(to,Signed))
# raise InexactError if x's top bit is set
@eval convert(::Type{$to}, x::($from)) = box($to,check_top_bit(unbox($from,x)))
@eval itrunc(::Type{$to}, x::($from)) = box($to,unbox($from,x))
else
@eval convert(::Type{$to}, x::($from)) = box($to,unbox($from,x))
end
end
end

itrunc{T<:Integer}(::Type{T}, x::T) = x
itrunc(::Type{Bool}, x::Integer) = ((x&1)!=0)

for to in (Int8, Int16, Int32, Int64)
@eval begin
convert(::Type{$to}, x::Float32) = box($to,checked_fptosi($to,unbox(Float32,x)))
Expand Down Expand Up @@ -240,8 +244,6 @@ uint32(x) = convert(Uint32,x)
uint64(x) = convert(Uint64,x)
uint128(x) = convert(Uint128,x)

signed(x) = convert(Signed,x)
unsigned(x) = convert(Unsigned,x)
integer(x) = convert(Integer,x)

round(x::Integer) = x
Expand Down Expand Up @@ -356,12 +358,12 @@ typemax(::Type{Uint64}) = 0xffffffffffffffff
@eval typemin(::Type{Int128} ) = $(convert(Int128,1)<<int32(127))
@eval typemax(::Type{Int128} ) = $(box(Int128,unbox(Uint128,typemax(Uint128)>>int32(1))))

widen(::Type{Int8}) = Int16
widen(::Type{Int16}) = Int32
widen(::Type{Int8}) = Int
widen(::Type{Int16}) = Int

This comment has been minimized.

Copy link
@timholy

timholy Sep 25, 2014

Member

Putting back widen(Int8)->Int does seem prudent.

widen(::Type{Int32}) = Int64
widen(::Type{Int64}) = Int128
widen(::Type{Uint8}) = Uint16
widen(::Type{Uint16}) = Uint32
widen(::Type{Uint8}) = Uint
widen(::Type{Uint16}) = Uint
widen(::Type{Uint32}) = Uint64
widen(::Type{Uint64}) = Uint128

Expand Down
5 changes: 2 additions & 3 deletions base/random.jl
Expand Up @@ -179,7 +179,7 @@ for (T, U) in [(Uint8, Uint32), (Uint16, Uint32),
(Int8, Uint32), (Int16, Uint32), (Int32, Uint32), (Int64, Uint64), (Int128, Uint128),
(Bool, Uint32), (Char, Uint32)]

@eval RandIntGen(r::UnitRange{$T}) = isempty(r) ? error("range must be non-empty") : RandIntGen(first(r), convert($U, last(r) - first(r) + 1)) # overflow ok
@eval RandIntGen(r::UnitRange{$T}) = isempty(r) ? error("range must be non-empty") : RandIntGen(first(r), convert($U, unsigned(last(r) - first(r) + one($T)))) # overflow ok
end

# this function uses 32 bit entropy for small ranges of length <= typemax(Uint32) + 1
Expand All @@ -205,8 +205,7 @@ function rand{T<:Integer, U<:Unsigned}(g::RandIntGen{T,U})
while x > g.u
x = rand(U)
end
# TODO: fix for when T is smaller than U
reinterpret(T, Base.asunsigned(g.a) + rem_knuth(x, g.k))
itrunc(T, g.a + rem_knuth(x, g.k))
end

rand{T<:Union(Signed,Unsigned,Bool,Char)}(r::UnitRange{T}) = rand(RandIntGen(r))
Expand Down
4 changes: 2 additions & 2 deletions base/range.jl
Expand Up @@ -39,9 +39,9 @@ immutable StepRange{T,S} <: OrdinalRange{T,S}
if T<:Signed && (diff > zero(diff)) != (stop > start)
# handle overflowed subtraction with unsigned rem
if diff > zero(diff)
remain = -oftype(T, asunsigned(-diff) % step)
remain = -oftype(T, unsigned(-diff) % step)
else
remain = oftype(T, asunsigned(diff) % step)
remain = oftype(T, unsigned(diff) % step)
end
else
remain = steprem(start,stop,step)
Expand Down
4 changes: 2 additions & 2 deletions base/utf16.jl
Expand Up @@ -11,7 +11,7 @@ end
utf16_is_lead(c::Uint16) = (c & 0xfc00) == 0xd800
utf16_is_trail(c::Uint16) = (c & 0xfc00) == 0xdc00
utf16_is_surrogate(c::Uint16) = (c & 0xf800) == 0xd800
utf16_get_supplementary(lead::Uint16, trail::Uint16) = char((lead-0xd7f7)<<10 + trail)
utf16_get_supplementary(lead::Uint16, trail::Uint16) = char(uint32(lead-0xd7f7)<<10 + trail)

function endof(s::UTF16String)
d = s.data
Expand Down Expand Up @@ -91,7 +91,7 @@ convert(T::Type{UTF16String}, data::AbstractArray{Int16}) =
function convert(T::Type{UTF16String}, bytes::AbstractArray{Uint8})
isempty(bytes) && return UTF16String(Uint16[0])
isodd(length(bytes)) && throw(ArgumentError("odd number of bytes"))
data = reinterpret(Uint16, bytes)
data = reinterpret(Uint16, bytes)
# check for byte-order mark (BOM):
if data[1] == 0xfeff # native byte order
d = Array(Uint16, length(data))
Expand Down
94 changes: 45 additions & 49 deletions test/numbers.jl
Expand Up @@ -1133,21 +1133,19 @@ end
@test cld(typemin(Int64)+3,-2) == 4611686018427387903
@test cld(typemin(Int64)+3,-7) == 1317624576693539401

import Base.asunsigned

for x={typemin(Int64), -typemax(Int64), -typemax(Int64)+1, -typemax(Int64)+2,
typemax(Int64)-2, typemax(Int64)-1, typemax(Int64),
typemax(Uint64)-1, typemax(Uint64)-2, typemax(Uint64)},
y={-7,-2,-1,1,2,7}
if x >= 0
@test div(asunsigned(x),y) == asunsigned(div(x,y))
@test fld(asunsigned(x),y) == asunsigned(fld(x,y))
@test cld(asunsigned(x),y) == asunsigned(cld(x,y))
@test div(unsigned(x),y) == unsigned(div(x,y))
@test fld(unsigned(x),y) == unsigned(fld(x,y))
@test cld(unsigned(x),y) == unsigned(cld(x,y))
end
if isa(x,Signed) && y >= 0
@test div(x,asunsigned(y)) == div(x,y)
@test fld(x,asunsigned(y)) == fld(x,y)
@test cld(x,asunsigned(y)) == cld(x,y)
@test div(x,unsigned(y)) == div(x,y)
@test fld(x,unsigned(y)) == fld(x,y)
@test cld(x,unsigned(y)) == cld(x,y)
end
end

Expand Down Expand Up @@ -1190,22 +1188,20 @@ end
@test div(typemax(Uint64)-2, 1) == typemax(Uint64)-2
@test div(typemax(Uint64)-2,-1) == -typemax(Uint64)+2

using Base.assigned

@test assigned(div(asunsigned(typemax(Int64))+2, 1)) == typemax(Int64)+2
@test assigned(div(asunsigned(typemax(Int64))+2,-1)) == -typemax(Int64)-2
@test assigned(div(asunsigned(typemax(Int64))+1, 1)) == typemax(Int64)+1
@test assigned(div(asunsigned(typemax(Int64))+1,-1)) == -typemax(Int64)-1
@test assigned(div(asunsigned(typemax(Int64)) , 1)) == typemax(Int64)
@test assigned(div(asunsigned(typemax(Int64)) ,-1)) == -typemax(Int64)

@test assigned(div(typemax(Uint),typemax(Int))) == 2
@test assigned(div(typemax(Uint),(typemax(Int)>>1)+1)) == 3
@test assigned(div(typemax(Uint),typemax(Int)>>1)) == 4
@test assigned(div(typemax(Uint),typemin(Int))) == -1
@test assigned(div(typemax(Uint),typemin(Int)+1)) == -2
@test assigned(div(typemax(Uint),typemin(Int)>>1)) == -3
@test assigned(div(typemax(Uint),(typemin(Int)>>1)+1)) == -4
@test signed(div(unsigned(typemax(Int64))+2, 1)) == typemax(Int64)+2
@test signed(div(unsigned(typemax(Int64))+2,-1)) == -typemax(Int64)-2
@test signed(div(unsigned(typemax(Int64))+1, 1)) == typemax(Int64)+1
@test signed(div(unsigned(typemax(Int64))+1,-1)) == -typemax(Int64)-1
@test signed(div(unsigned(typemax(Int64)) , 1)) == typemax(Int64)
@test signed(div(unsigned(typemax(Int64)) ,-1)) == -typemax(Int64)

@test signed(div(typemax(Uint),typemax(Int))) == 2
@test signed(div(typemax(Uint),(typemax(Int)>>1)+1)) == 3
@test signed(div(typemax(Uint),typemax(Int)>>1)) == 4
@test signed(div(typemax(Uint),typemin(Int))) == -1
@test signed(div(typemax(Uint),typemin(Int)+1)) == -2
@test signed(div(typemax(Uint),typemin(Int)>>1)) == -3
@test signed(div(typemax(Uint),(typemin(Int)>>1)+1)) == -4

@test fld(typemax(Uint64) , 1) == typemax(Uint64)
@test fld(typemax(Uint64) ,-1) == -typemax(Uint64)
Expand All @@ -1214,20 +1210,20 @@ using Base.assigned
@test fld(typemax(Uint64)-2, 1) == typemax(Uint64)-2
@test fld(typemax(Uint64)-2,-1) == -typemax(Uint64)+2

@test assigned(fld(asunsigned(typemax(Int64))+2, 1)) == typemax(Int64)+2
@test assigned(fld(asunsigned(typemax(Int64))+2,-1)) == -typemax(Int64)-2
@test assigned(fld(asunsigned(typemax(Int64))+1, 1)) == typemax(Int64)+1
@test assigned(fld(asunsigned(typemax(Int64))+1,-1)) == -typemax(Int64)-1
@test assigned(fld(asunsigned(typemax(Int64)) , 1)) == typemax(Int64)
@test assigned(fld(asunsigned(typemax(Int64)) ,-1)) == -typemax(Int64)

@test assigned(fld(typemax(Uint),typemax(Int))) == 2
@test assigned(fld(typemax(Uint),(typemax(Int)>>1)+1)) == 3
@test assigned(fld(typemax(Uint),typemax(Int)>>1)) == 4
@test assigned(fld(typemax(Uint),typemin(Int))) == -2
@test assigned(fld(typemax(Uint),typemin(Int)+1)) == -3
@test assigned(fld(typemax(Uint),typemin(Int)>>1)) == -4
@test assigned(fld(typemax(Uint),(typemin(Int)>>1)+1)) == -5
@test signed(fld(unsigned(typemax(Int64))+2, 1)) == typemax(Int64)+2
@test signed(fld(unsigned(typemax(Int64))+2,-1)) == -typemax(Int64)-2
@test signed(fld(unsigned(typemax(Int64))+1, 1)) == typemax(Int64)+1
@test signed(fld(unsigned(typemax(Int64))+1,-1)) == -typemax(Int64)-1
@test signed(fld(unsigned(typemax(Int64)) , 1)) == typemax(Int64)
@test signed(fld(unsigned(typemax(Int64)) ,-1)) == -typemax(Int64)

@test signed(fld(typemax(Uint),typemax(Int))) == 2
@test signed(fld(typemax(Uint),(typemax(Int)>>1)+1)) == 3
@test signed(fld(typemax(Uint),typemax(Int)>>1)) == 4
@test signed(fld(typemax(Uint),typemin(Int))) == -2
@test signed(fld(typemax(Uint),typemin(Int)+1)) == -3
@test signed(fld(typemax(Uint),typemin(Int)>>1)) == -4
@test signed(fld(typemax(Uint),(typemin(Int)>>1)+1)) == -5

@test cld(typemax(Uint64) , 1) == typemax(Uint64)
@test cld(typemax(Uint64) ,-1) == -typemax(Uint64)
Expand All @@ -1236,20 +1232,20 @@ using Base.assigned
@test cld(typemax(Uint64)-2, 1) == typemax(Uint64)-2
@test cld(typemax(Uint64)-2,-1) == -typemax(Uint64)+2

@test assigned(cld(asunsigned(typemax(Int64))+2, 1)) == typemax(Int64)+2
@test assigned(cld(asunsigned(typemax(Int64))+2,-1)) == -typemax(Int64)-2
@test assigned(cld(asunsigned(typemax(Int64))+1, 1)) == typemax(Int64)+1
@test assigned(cld(asunsigned(typemax(Int64))+1,-1)) == -typemax(Int64)-1
@test assigned(cld(asunsigned(typemax(Int64)) , 1)) == typemax(Int64)
@test assigned(cld(asunsigned(typemax(Int64)) ,-1)) == -typemax(Int64)
@test signed(cld(unsigned(typemax(Int64))+2, 1)) == typemax(Int64)+2
@test signed(cld(unsigned(typemax(Int64))+2,-1)) == -typemax(Int64)-2
@test signed(cld(unsigned(typemax(Int64))+1, 1)) == typemax(Int64)+1
@test signed(cld(unsigned(typemax(Int64))+1,-1)) == -typemax(Int64)-1
@test signed(cld(unsigned(typemax(Int64)) , 1)) == typemax(Int64)
@test signed(cld(unsigned(typemax(Int64)) ,-1)) == -typemax(Int64)

@test signed(cld(typemax(Uint),typemax(Int))) == 3
@test signed(cld(typemax(Uint),(typemax(Int)>>1)+1)) == 4
@test signed(cld(typemax(Uint),typemax(Int)>>1)) == 5
@test assigned(cld(typemax(Uint),typemin(Int))) == -1
@test assigned(cld(typemax(Uint),typemin(Int)+1)) == -2
@test assigned(cld(typemax(Uint),typemin(Int)>>1)) == -3
@test assigned(cld(typemax(Uint),(typemin(Int)>>1)+1)) == -4
@test signed(cld(typemax(Uint),typemin(Int))) == -1
@test signed(cld(typemax(Uint),typemin(Int)+1)) == -2
@test signed(cld(typemax(Uint),typemin(Int)>>1)) == -3
@test signed(cld(typemax(Uint),(typemin(Int)>>1)+1)) == -4

# issue #4156
@test fld(1.4,0.35667494393873234) == 3.0
Expand Down Expand Up @@ -1935,7 +1931,7 @@ end
# widen
@test widen(1.5f0) === 1.5
@test widen(int32(42)) === int64(42)
@test widen(Int8) === Int16
@test widen(Int8) === Int
@test widen(Float32) === Float64
## Note: this should change to e.g. Float128 at some point
@test widen(Float64) === BigFloat
Expand Down

0 comments on commit 16c2330

Please sign in to comment.