From 16c2330da55ed9b9eb84353a292db495aad562b7 Mon Sep 17 00:00:00 2001 From: Jeff Bezanson Date: Thu, 25 Sep 2014 15:18:47 -0400 Subject: [PATCH] make signed() and unsigned() unchecked. check only in convert() a few fixes in base for the convert and arithmetic changes get all tests passing --- base/char.jl | 4 +- base/datafmt.jl | 2 +- base/grisu/fastfixed.jl | 6 +-- base/int.jl | 48 +++++++++++---------- base/random.jl | 5 +-- base/range.jl | 4 +- base/utf16.jl | 4 +- test/numbers.jl | 94 ++++++++++++++++++++--------------------- 8 files changed, 82 insertions(+), 85 deletions(-) diff --git a/base/char.jl b/base/char.jl index 05cb6124e1c70..606ed400f24de 100644 --- a/base/char.jl +++ b/base/char.jl @@ -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 diff --git a/base/datafmt.jl b/base/datafmt.jl index a99e97e73f489..e90616443edcf 100644 --- a/base/datafmt.jl +++ b/base/datafmt.jl @@ -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 diff --git a/base/grisu/fastfixed.jl b/base/grisu/fastfixed.jl index 638782727a6bd..22bd4e4e68f54 100644 --- a/base/grisu/fastfixed.jl +++ b/base/grisu/fastfixed.jl @@ -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) @@ -219,4 +219,4 @@ function fastfixedtoa(v,mode,fractional_count,buffer) decimal_point = -fractional_count end return true, len, decimal_point, buffer -end \ No newline at end of file +end diff --git a/base/int.jl b/base/int.jl index b55897cba5901..4da95ddd92bdd 100644 --- a/base/int.jl +++ b/base/int.jl @@ -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)) @@ -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 ## @@ -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))) @@ -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 @@ -356,12 +358,12 @@ typemax(::Type{Uint64}) = 0xffffffffffffffff @eval typemin(::Type{Int128} ) = $(convert(Int128,1)<>int32(1)))) -widen(::Type{Int8}) = Int16 -widen(::Type{Int16}) = Int32 +widen(::Type{Int8}) = Int +widen(::Type{Int16}) = Int 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 diff --git a/base/random.jl b/base/random.jl index 4e58b3bd5184d..70c439cbb705e 100644 --- a/base/random.jl +++ b/base/random.jl @@ -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 @@ -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)) diff --git a/base/range.jl b/base/range.jl index dcda238d4d07f..6979e3575ffa2 100644 --- a/base/range.jl +++ b/base/range.jl @@ -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) diff --git a/base/utf16.jl b/base/utf16.jl index 29c496dca7f6e..be313bacae6d8 100644 --- a/base/utf16.jl +++ b/base/utf16.jl @@ -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 @@ -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)) diff --git a/test/numbers.jl b/test/numbers.jl index 5d3620fd7d8b2..5606e1035322c 100644 --- a/test/numbers.jl +++ b/test/numbers.jl @@ -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 @@ -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) @@ -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) @@ -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 @@ -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