diff --git a/base/float.jl b/base/float.jl index 96e3317b57bfb..ef6fdc1d77e37 100644 --- a/base/float.jl +++ b/base/float.jl @@ -6,10 +6,12 @@ convert(::Type{Float32}, x::Int8) = box(Float32,sitofp32(unbox(Int8,x))) convert(::Type{Float32}, x::Int16) = box(Float32,sitofp32(unbox(Int16,x))) convert(::Type{Float32}, x::Int32) = box(Float32,sitofp32(unbox(Int32,x))) convert(::Type{Float32}, x::Int64) = box(Float32,sitofp32(unbox(Int64,x))) +convert(::Type{Float32}, x::Int128) = float32(uint128(abs(x)))*(1-2(x<0)) convert(::Type{Float32}, x::Uint8) = box(Float32,uitofp32(unbox(Uint8,x))) convert(::Type{Float32}, x::Uint16) = box(Float32,uitofp32(unbox(Uint16,x))) convert(::Type{Float32}, x::Uint32) = box(Float32,uitofp32(unbox(Uint32,x))) convert(::Type{Float32}, x::Uint64) = box(Float32,uitofp32(unbox(Uint64,x))) +convert(::Type{Float32}, x::Uint128) = float32(uint64(x)) + ldexp(float32(uint64(x>>>64)),64) convert(::Type{Float32}, x::Float64) = box(Float32,fptrunc32(unbox(Float64,x))) convert(::Type{Float64}, x::Bool) = box(Float64,uitofp64(unbox(Bool,x))) @@ -18,22 +20,26 @@ convert(::Type{Float64}, x::Int8) = box(Float64,sitofp64(unbox(Int8,x))) convert(::Type{Float64}, x::Int16) = box(Float64,sitofp64(unbox(Int16,x))) convert(::Type{Float64}, x::Int32) = box(Float64,sitofp64(unbox(Int32,x))) convert(::Type{Float64}, x::Int64) = box(Float64,sitofp64(unbox(Int64,x))) +convert(::Type{Float64}, x::Int128) = float64(uint128(abs(x)))*(1-2(x<0)) convert(::Type{Float64}, x::Uint8) = box(Float64,uitofp64(unbox(Uint8,x))) convert(::Type{Float64}, x::Uint16) = box(Float64,uitofp64(unbox(Uint16,x))) convert(::Type{Float64}, x::Uint32) = box(Float64,uitofp64(unbox(Uint32,x))) convert(::Type{Float64}, x::Uint64) = box(Float64,uitofp64(unbox(Uint64,x))) +convert(::Type{Float64}, x::Uint128) = float64(uint64(x)) + ldexp(float64(uint64(x>>>64)),64) convert(::Type{Float64}, x::Float32) = box(Float64,fpext64(unbox(Float32,x))) -convert(::Type{FloatingPoint}, x::Bool) = convert(Float32, x) -convert(::Type{FloatingPoint}, x::Char) = convert(Float32, x) -convert(::Type{FloatingPoint}, x::Int8) = convert(Float32, x) -convert(::Type{FloatingPoint}, x::Int16) = convert(Float32, x) -convert(::Type{FloatingPoint}, x::Int32) = convert(Float64, x) -convert(::Type{FloatingPoint}, x::Int64) = convert(Float64, x) # LOSSY -convert(::Type{FloatingPoint}, x::Uint8) = convert(Float32, x) -convert(::Type{FloatingPoint}, x::Uint16) = convert(Float32, x) -convert(::Type{FloatingPoint}, x::Uint32) = convert(Float64, x) -convert(::Type{FloatingPoint}, x::Uint64) = convert(Float64, x) # LOSSY +convert(::Type{FloatingPoint}, x::Bool) = convert(Float32, x) +convert(::Type{FloatingPoint}, x::Char) = convert(Float32, x) +convert(::Type{FloatingPoint}, x::Int8) = convert(Float32, x) +convert(::Type{FloatingPoint}, x::Int16) = convert(Float32, x) +convert(::Type{FloatingPoint}, x::Int32) = convert(Float64, x) +convert(::Type{FloatingPoint}, x::Int64) = convert(Float64, x) # LOSSY +convert(::Type{FloatingPoint}, x::Int128) = convert(Float64, x) # LOSSY +convert(::Type{FloatingPoint}, x::Uint8) = convert(Float32, x) +convert(::Type{FloatingPoint}, x::Uint16) = convert(Float32, x) +convert(::Type{FloatingPoint}, x::Uint32) = convert(Float64, x) +convert(::Type{FloatingPoint}, x::Uint64) = convert(Float64, x) # LOSSY +convert(::Type{FloatingPoint}, x::Uint128) = convert(Float64, x) # LOSSY float32(x) = convert(Float32, x) float64(x) = convert(Float64, x) @@ -69,7 +75,10 @@ iround(::Type{Int64}, x::Float32) = box(Int64,fpsiround64(fpext64(unbox(Float32, iround(::Type{Int64}, x::Float64) = box(Int64,fpsiround64(unbox(Float64,x))) iround(::Type{Uint64}, x::Float32) = box(Uint64,fpuiround64(fpext64(unbox(Float32,x)))) iround(::Type{Uint64}, x::Float64) = box(Uint64,fpuiround64(unbox(Float64,x))) -# TODO: Int128 +iround(::Type{Int128}, x::Float32) = convert(Int128,round(x)) +iround(::Type{Int128}, x::Float64) = convert(Int128,round(x)) +iround(::Type{Uint128}, x::Float32) = convert(Uint128,round(x)) +iround(::Type{Uint128}, x::Float64) = convert(Uint128,round(x)) # this is needed very early because it is used by Range and colon floor(x::Float64) = ccall((:floor, Base.libm_name), Float64, (Float64,), x) diff --git a/base/int.jl b/base/int.jl index 71dcc8d285a9d..0ca7d9beb1c67 100644 --- a/base/int.jl +++ b/base/int.jl @@ -123,8 +123,14 @@ convert(::Type{Int128}, x::Uint32 ) = box(Int128,zext_int(Uint128,unbox(Uint32,x convert(::Type{Int128}, x::Int64 ) = box(Int128,sext_int(Int128,unbox(Int64,x))) convert(::Type{Int128}, x::Uint64 ) = box(Int128,zext_int(Uint128,unbox(Uint64,x))) convert(::Type{Int128}, x::Uint128) = box(Int128,unbox(Uint128,x)) -# TODO: convert(::Type{Int128}, x::Float32) -# TODO: convert(::Type{Int128}, x::Float64) +function convert(::Type{Int128}, x::Float64) + ax = abs(x) + top = trunc(ldexp(ax,-64)) + bot = ax - ldexp(top,64) + n = int128(convert(Uint64,top))<<64 + int128(convert(Uint64,bot)) + return x<0 ? -n : n +end +convert(::Type{Int128}, x::Float32) = convert(Int128, float64(x)) convert(::Type{Uint128}, x::Bool ) = box(Uint128,zext_int(Int128,unbox(Bool,x))) convert(::Type{Uint128}, x::Int8 ) = box(Uint128,sext_int(Int128,unbox(Int8,x))) @@ -137,8 +143,14 @@ convert(::Type{Uint128}, x::Uint32 ) = box(Uint128,zext_int(Uint128,unbox(Uint32 convert(::Type{Uint128}, x::Int64 ) = box(Uint128,sext_int(Int128,unbox(Int64,x))) convert(::Type{Uint128}, x::Uint64 ) = box(Uint128,zext_int(Uint128,unbox(Uint64,x))) convert(::Type{Uint128}, x::Int128 ) = box(Uint128,unbox(Int128,x)) -# TODO: convert(::Type{Uint128}, x::Float32) -# TODO: convert(::Type{Uint128}, x::Float64) +function convert(::Type{Uint128}, x::Float64) + ax = abs(x) + top = trunc(ldexp(ax,-64)) + bot = ax - ldexp(top,64) + n = uint128(convert(Uint64,top))<<64 + uint128(convert(Uint64,bot)) + return x<0 ? -n : n +end +convert(::Type{Uint128}, x::Float32) = convert(Uint128, float64(x)) convert(::Type{Signed}, x::Uint8 ) = convert(Int,x) convert(::Type{Signed}, x::Uint16 ) = convert(Int,x) diff --git a/test/numbers.jl b/test/numbers.jl index 608b70c362425..40ee38d13dd28 100644 --- a/test/numbers.jl +++ b/test/numbers.jl @@ -619,6 +619,27 @@ end @test typemax(Uint64) != 2.0^64 +@test float64(int128(0)) == 0.0 +@test float32(int128(0)) == 0.0f0 +@test float64(int128(-1)) == -1.0 +@test float32(int128(-1)) == -1.0f0 +@test float64(int128(3)) == 3.0 +@test float32(int128(3)) == 3.0f0 +@test float64(uint128(10121)) == 10121.0 +@test float32(uint128(10121)) == 10121.0f0 +@test float64(typemin(Int128)) == -2.0^127 +@test float32(typemin(Int128)) == -2.0f0^127 +@test float64(typemax(Int128)) == 2.0^127 +@test float32(typemax(Int128)) == 2.0f0^127 +@test float64(typemin(Uint128)) == 0.0 +@test float32(typemin(Uint128)) == 0.0f0 +@test float64(typemax(Uint128)) == 2.0^128 +@test float32(typemax(Uint128)) == 2.0f0^128 + +@test int128(-2.0^127) == typemin(Int128) +@test float64(uint128(3.7e19)) == 3.7e19 +@test float64(uint128(3.7e30)) == 3.7e30 + @test !(NaN <= 1) @test !(NaN >= 1) @test !(NaN < 1)