diff --git a/base/boot.jl b/base/boot.jl index d054fad583e06..e34d15354e379 100644 --- a/base/boot.jl +++ b/base/boot.jl @@ -151,7 +151,7 @@ export #ccall, cglobal, llvmcall, abs_float, add_float, add_int, and_int, ashr_int, #box, bswap_int, checked_fptosi, checked_fptoui, checked_sadd, #checked_smul, checked_ssub, checked_uadd, checked_umul, checked_usub, - #checked_trunc_sint, checked_trunc_uint, + #checked_trunc_sint, checked_trunc_uint, check_top_bit, #nan_dom_err, copysign_float, ctlz_int, ctpop_int, cttz_int, #div_float, eq_float, eq_int, eqfsi64, eqfui64, flipsign_int, select_value, #sqrt_llvm, powi_llvm, diff --git a/base/dict.jl b/base/dict.jl index 44008c39f6962..5381a97770d6c 100644 --- a/base/dict.jl +++ b/base/dict.jl @@ -288,7 +288,7 @@ end empty!(t::ObjectIdDict) = (t.ht = cell(length(t.ht)); t) -_oidd_nextind(a, i) = int(ccall(:jl_eqtable_nextind, Csize_t, (Any, Csize_t), a, i)) +_oidd_nextind(a, i) = reinterpret(Int,ccall(:jl_eqtable_nextind, Csize_t, (Any, Csize_t), a, i)) start(t::ObjectIdDict) = _oidd_nextind(t.ht, 0) done(t::ObjectIdDict, i) = (i == -1) diff --git a/base/int.jl b/base/int.jl index 69cb22a4f875c..85760b852cd2d 100644 --- a/base/int.jl +++ b/base/int.jl @@ -43,17 +43,17 @@ abs(x::Signed) = flipsign(x,x) ~(n::Integer) = -n-1 -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)) +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)) -rem(x::Signed, y::Unsigned) = flipsign(signed(rem(unsigned(abs(x)),y)),x) -rem(x::Unsigned, y::Signed) = rem(x,unsigned(abs(y))) +rem(x::Signed, y::Unsigned) = flipsign(assigned(rem(asunsigned(abs(x)),y)),x) +rem(x::Unsigned, y::Signed) = rem(x,asunsigned(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+unsigned(rem(x,y)),y) -mod(x::Unsigned, y::Signed) = rem(y+signed(rem(x,y)),y) +mod(x::Signed, y::Unsigned) = rem(y+asunsigned(rem(x,y)),y) +mod(x::Unsigned, y::Signed) = rem(y+assigned(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)) @@ -133,6 +133,7 @@ for T in IntTypes end asunsigned(x) = reinterpret(typeof(unsigned(zero(x))), x) +assigned(x) = reinterpret(typeof(signed(zero(x))), x) ==(x::Signed, y::Unsigned) = (x >= 0) & (asunsigned(x) == y) ==(x::Unsigned, y::Signed ) = (y >= 0) & (x == asunsigned(y)) @@ -158,6 +159,9 @@ for to in tuple(IntTypes...,Char), from in tuple(IntTypes...,Char,Bool) else @eval convert(::Type{$to}, x::($from)) = box($to,zext_int($to,unbox($from,x))) end + 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))) else @eval convert(::Type{$to}, x::($from)) = box($to,unbox($from,x)) end @@ -223,7 +227,8 @@ int32(x) = convert(Int32,x) int64(x) = convert(Int64,x) int128(x) = convert(Int128,x) -uint8(x) = convert(Uint8,x) +uint8(x) = itrunc(Uint8,x) +uint8(x::Int8) = box(Uint8,unbox(Int8,x)) uint16(x) = convert(Uint16,x) uint32(x) = convert(Uint32,x) uint64(x) = convert(Uint64,x) diff --git a/base/intfuncs.jl b/base/intfuncs.jl index 077b363eed90b..37592d98fecec 100644 --- a/base/intfuncs.jl +++ b/base/intfuncs.jl @@ -109,10 +109,10 @@ end # smallest power of 2 >= x nextpow2(x::Unsigned) = one(x)<<((sizeof(x)<<3)-leading_zeros(x-1)) -nextpow2(x::Integer) = oftype(x,x < 0 ? -nextpow2(unsigned(-x)) : nextpow2(unsigned(x))) +nextpow2(x::Integer) = reinterpret(typeof(x),x < 0 ? -nextpow2(unsigned(-x)) : nextpow2(unsigned(x))) prevpow2(x::Unsigned) = (one(x)>>(x==0)) << ((sizeof(x)<<3)-leading_zeros(x)-1) -prevpow2(x::Integer) = oftype(x,x < 0 ? -prevpow2(unsigned(-x)) : prevpow2(unsigned(x))) +prevpow2(x::Integer) = reinterpret(typeof(x),x < 0 ? -prevpow2(unsigned(-x)) : prevpow2(unsigned(x))) ispow2(x::Integer) = count_ones(x)==1 @@ -154,7 +154,7 @@ function ndigits0z(x::Uint128) end return n + ndigits0z(uint64(x)) end -ndigits0z(x::Integer) = ndigits0z(unsigned(abs(x))) +ndigits0z(x::Integer) = ndigits0z(asunsigned(abs(x))) const ndigits_max_mul = WORD_SIZE==32 ? 69000000 : 290000000000000000 @@ -175,13 +175,13 @@ function ndigits0z(n::Unsigned, b::Int) end return d end -ndigits0z(x::Integer, b::Integer) = ndigits0z(unsigned(abs(x)),int(b)) +ndigits0z(x::Integer, b::Integer) = ndigits0z(asunsigned(abs(x)),int(b)) ndigits(x::Unsigned, b::Integer) = x==0 ? 1 : ndigits0z(x,int(b)) ndigits(x::Unsigned) = x==0 ? 1 : ndigits0z(x) -ndigits(x::Integer, b::Integer) = ndigits(unsigned(abs(x)),int(b)) -ndigits(x::Integer) = ndigits(unsigned(abs(x))) +ndigits(x::Integer, b::Integer) = ndigits(asunsigned(abs(x)),int(b)) +ndigits(x::Integer) = ndigits(asunsigned(abs(x))) ## integer to string functions ## @@ -252,7 +252,7 @@ function base(b::Int, x::Unsigned, pad::Int, neg::Bool) if neg; a[1]='-'; end ASCIIString(a) end -base(b::Integer, n::Integer, pad::Integer=1) = base(int(b), unsigned(abs(n)), pad, n<0) +base(b::Integer, n::Integer, pad::Integer=1) = base(int(b), asunsigned(abs(n)), pad, n<0) for sym in (:bin, :oct, :dec, :hex) @eval begin @@ -260,8 +260,8 @@ for sym in (:bin, :oct, :dec, :hex) ($sym)(x::Unsigned) = ($sym)(x,1,false) ($sym)(x::Char, p::Int) = ($sym)(unsigned(x),p,false) ($sym)(x::Char) = ($sym)(unsigned(x),1,false) - ($sym)(x::Integer, p::Int) = ($sym)(unsigned(abs(x)),p,x<0) - ($sym)(x::Integer) = ($sym)(unsigned(abs(x)),1,x<0) + ($sym)(x::Integer, p::Int) = ($sym)(asunsigned(abs(x)),p,x<0) + ($sym)(x::Integer) = ($sym)(asunsigned(abs(x)),1,x<0) end end diff --git a/base/number.jl b/base/number.jl index a0b641346e040..350418e75da18 100644 --- a/base/number.jl +++ b/base/number.jl @@ -39,11 +39,11 @@ done(x::Number, state) = state isempty(x::Number) = false in(x::Number, y::Number) = x == y -function reinterpret{T}(::Type{T}, x) +function reinterpret{T,S}(::Type{T}, x::S) if !isbits(T) error("cannot reinterpret to type ", T) end - box(T,x) + box(T,unbox(S,x)) end map(f::Callable, x::Number) = f(x) diff --git a/src/intrinsics.cpp b/src/intrinsics.cpp index 1a6a4518adf01..8f0b0b22b25c9 100644 --- a/src/intrinsics.cpp +++ b/src/intrinsics.cpp @@ -28,7 +28,7 @@ namespace JL_I { fptrunc, fpext, // checked conversion fpsiround, fpuiround, checked_fptosi, checked_fptoui, - checked_trunc_sint, checked_trunc_uint, + checked_trunc_sint, checked_trunc_uint, check_top_bit, // checked arithmetic checked_sadd, checked_uadd, checked_ssub, checked_usub, checked_smul, checked_umul, @@ -1089,6 +1089,16 @@ static Value *emit_intrinsic(intrinsic f, jl_value_t **args, size_t nargs, return builder.CreateExtractValue(res, ArrayRef(0)); } + HANDLE(check_top_bit,1) + // raise InexactError if argument's top bit is set + x = JL_INT(x); + raise_exception_if(builder. + CreateTrunc(builder. + CreateLShr(x, ConstantInt::get(t, t->getPrimitiveSizeInBits()-1)), + T_int1), + prepare_global(jlinexacterr_var), ctx); + return x; + HANDLE(eq_int,2) return builder.CreateICmpEQ(JL_INT(x), JL_INT(y)); HANDLE(ne_int,2) return builder.CreateICmpNE(JL_INT(x), JL_INT(y)); HANDLE(slt_int,2) return builder.CreateICmpSLT(JL_INT(x), JL_INT(y)); @@ -1503,6 +1513,7 @@ extern "C" void jl_init_intrinsic_functions(void) ADD_I(checked_fptosi); ADD_I(checked_fptoui); ADD_I(checked_trunc_sint); ADD_I(checked_trunc_uint); + ADD_I(check_top_bit); ADD_I(nan_dom_err); ADD_I(ccall); ADD_I(cglobal); ADD_I(jl_alloca); diff --git a/test/core.jl b/test/core.jl index cc5c712be1f31..d545b222be4d5 100644 --- a/test/core.jl +++ b/test/core.jl @@ -243,31 +243,31 @@ end # conversions function fooo() local x::Int8 - x = 1000 + x = 100 x end -@test int32(fooo()) == -24 +@test fooo() === convert(Int8,100) function fooo_2() local x::Int8 - x = 1000 + x = 100 end -@test fooo_2() == 1000 +@test fooo_2() === 100 function fooo_3() local x::Int8 - y = x = 1000 - @test x == -24 + y = x = 100 + @test isa(x,Int8) y end -@test fooo_3() == 1000 +@test fooo_3() === 100 function foo() local x::Int8 function bar() - x = 1000 + x = 100 end bar() x end -@test int32(foo()) == -24 +@test foo() === convert(Int8,100) function bar{T}(x::T) local z::Complex{T} diff --git a/test/numbers.jl b/test/numbers.jl index 0c6473cd3a747..5d3620fd7d8b2 100644 --- a/test/numbers.jl +++ b/test/numbers.jl @@ -802,15 +802,15 @@ end for T in {Int8,Int16,Int32,Int64,Int128} @test abs(typemin(T)) == -typemin(T) - for x in {typemin(T),convert(T,-1),zero(T),one(T),typemax(T)} - @test signed(unsigned(x)) == x - end + #for x in {typemin(T),convert(T,-1),zero(T),one(T),typemax(T)} + # @test signed(unsigned(x)) == x + #end end -for T in {Uint8,Uint16,Uint32,Uint64,Uint128}, - x in {typemin(T),one(T),typemax(T)} - @test unsigned(signed(x)) == x -end +#for T in {Uint8,Uint16,Uint32,Uint64,Uint128}, +# x in {typemin(T),one(T),typemax(T)} +# @test unsigned(signed(x)) == x +#end for S = {Int8, Int16, Int32, Int64}, U = {Uint8, Uint16, Uint32, Uint64} @@ -1133,19 +1133,21 @@ 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(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)) + @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)) end if isa(x,Signed) && y >= 0 - @test div(x,unsigned(y)) == div(x,y) - @test fld(x,unsigned(y)) == fld(x,y) - @test cld(x,unsigned(y)) == cld(x,y) + @test div(x,asunsigned(y)) == div(x,y) + @test fld(x,asunsigned(y)) == fld(x,y) + @test cld(x,asunsigned(y)) == cld(x,y) end end @@ -1153,19 +1155,19 @@ for x=0:5, y=1:5 @test div(uint(x),uint(y)) == div(x,y) @test div(uint(x),y) == div(x,y) @test div(x,uint(y)) == div(x,y) - @test div(uint(x),-y) == uint(div(x,-y)) + @test div(uint(x),-y) == reinterpret(Uint,div(x,-y)) @test div(-x,uint(y)) == div(-x,y) @test fld(uint(x),uint(y)) == fld(x,y) @test fld(uint(x),y) == fld(x,y) @test fld(x,uint(y)) == fld(x,y) - @test fld(uint(x),-y) == uint(fld(x,-y)) + @test fld(uint(x),-y) == reinterpret(Uint,fld(x,-y)) @test fld(-x,uint(y)) == fld(-x,y) @test cld(uint(x),uint(y)) == cld(x,y) @test cld(uint(x),y) == cld(x,y) @test cld(x,uint(y)) == cld(x,y) - @test cld(uint(x),-y) == uint(cld(x,-y)) + @test cld(uint(x),-y) == reinterpret(Uint,cld(x,-y)) @test cld(-x,uint(y)) == cld(-x,y) @test rem(uint(x),uint(y)) == rem(x,y) @@ -1188,20 +1190,22 @@ end @test div(typemax(Uint64)-2, 1) == typemax(Uint64)-2 @test div(typemax(Uint64)-2,-1) == -typemax(Uint64)+2 -@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 +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 fld(typemax(Uint64) , 1) == typemax(Uint64) @test fld(typemax(Uint64) ,-1) == -typemax(Uint64) @@ -1210,20 +1214,20 @@ end @test fld(typemax(Uint64)-2, 1) == typemax(Uint64)-2 @test fld(typemax(Uint64)-2,-1) == -typemax(Uint64)+2 -@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 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 cld(typemax(Uint64) , 1) == typemax(Uint64) @test cld(typemax(Uint64) ,-1) == -typemax(Uint64) @@ -1232,20 +1236,20 @@ end @test cld(typemax(Uint64)-2, 1) == typemax(Uint64)-2 @test cld(typemax(Uint64)-2,-1) == -typemax(Uint64)+2 -@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 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(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 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 +@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 # issue #4156 @test fld(1.4,0.35667494393873234) == 3.0