From a953172581b5bb8cefc22ca9535555b2dfdebc3b Mon Sep 17 00:00:00 2001 From: Jeff Bezanson Date: Sat, 15 Mar 2014 15:20:02 -0400 Subject: [PATCH] document and export `widen`. closes #6169 --- NEWS.md | 3 +++ base/combinatorics.jl | 4 ++-- base/exports.jl | 1 + base/float.jl | 4 ++-- base/gmp.jl | 6 +++++- base/int.jl | 16 ++++++++-------- base/mpfr.jl | 5 ++++- base/operators.jl | 2 ++ doc/stdlib/base.rst | 9 +++++++++ test/numbers.jl | 9 +++++++++ 10 files changed, 45 insertions(+), 14 deletions(-) diff --git a/NEWS.md b/NEWS.md index 23c96f94fc9b8..ef0eb3b625283 100644 --- a/NEWS.md +++ b/NEWS.md @@ -221,6 +221,8 @@ Library improvements * Ranges and arrays with the same elements are now unequal. This allows hashing and comparing ranges to be faster. ([#5778]) + * New function `widen` for widening numeric types and values ([#6169]) + Deprecated or removed --------------------- @@ -322,6 +324,7 @@ Deprecated or removed [#5737]: https://github.com/JuliaLang/julia/issues/5737 [#6073]: https://github.com/JuliaLang/julia/issues/6073 [#5778]: https://github.com/JuliaLang/julia/issues/5778 +[#6169]: https://github.com/JuliaLang/julia/issues/6169 Julia v0.2.0 Release Notes ========================== diff --git a/base/combinatorics.jl b/base/combinatorics.jl index 379220ff344ab..e291428ea8aac 100644 --- a/base/combinatorics.jl +++ b/base/combinatorics.jl @@ -531,7 +531,7 @@ function nextprod(a::Vector{Int}, x) v = ones(Int, k) # current value of each counter mx = [nextpow(ai,x) for ai in a] # maximum value of each counter v[1] = mx[1] # start at first case that is >= x - p::morebits(Int) = mx[1] # initial value of product in this case + p::widen(Int) = mx[1] # initial value of product in this case best = p icarry = 1 @@ -573,7 +573,7 @@ function prevprod(a::Vector{Int}, x) mx = [nextpow(ai,x) for ai in a] # allow each counter to exceed p (sentinel) first = int(prevpow(a[1], x)) # start at best case in first factor v[1] = first - p::morebits(Int) = first + p::widen(Int) = first best = p icarry = 1 diff --git a/base/exports.jl b/base/exports.jl index 198f424c9ce6a..5e5b3c3589627 100644 --- a/base/exports.jl +++ b/base/exports.jl @@ -982,6 +982,7 @@ export super, typeintersect, typejoin, + widen, # syntax esc, diff --git a/base/float.jl b/base/float.jl index 4447ab5ad82e4..979b4f19ac2f9 100644 --- a/base/float.jl +++ b/base/float.jl @@ -113,8 +113,8 @@ promote_rule(::Type{Float32}, ::Type{Float16}) = Float32 promote_rule(::Type{Float64}, ::Type{Float16}) = Float64 promote_rule(::Type{Float64}, ::Type{Float32}) = Float64 -morebits(::Type{Float16}) = Float32 -morebits(::Type{Float32}) = Float64 +widen(::Type{Float16}) = Float32 +widen(::Type{Float32}) = Float64 ## floating point arithmetic ## diff --git a/base/gmp.jl b/base/gmp.jl index 11eb0dd9653aa..1dccf75722829 100644 --- a/base/gmp.jl +++ b/base/gmp.jl @@ -7,7 +7,7 @@ import Base: *, +, -, /, <, <<, >>, >>>, <=, ==, >, >=, ^, (~), (&), (|), ($), ndigits, promote_rule, rem, show, isqrt, string, isprime, powermod, widemul, sum, trailing_zeros, trailing_ones, count_ones, base, parseint, serialize, deserialize, bin, oct, dec, hex, isequal, invmod, - prevpow2, nextpow2, ndigits0z + prevpow2, nextpow2, ndigits0z, widen type BigInt <: Integer alloc::Cint @@ -34,6 +34,10 @@ function __init__() cglobal(:jl_gc_counted_free)) end +widen(::Type{Int128}) = BigInt +widen(::Type{Uint128}) = BigInt +widen(::Type{BigInt}) = BigInt + BigInt(x::BigInt) = x BigInt(s::String) = parseint(BigInt,s) diff --git a/base/int.jl b/base/int.jl index 9009726cb9cdb..dd8a842c1ff3d 100644 --- a/base/int.jl +++ b/base/int.jl @@ -460,14 +460,14 @@ sizeof(::Type{Uint64}) = 8 sizeof(::Type{Int128}) = 16 sizeof(::Type{Uint128}) = 16 -morebits(::Type{Int8}) = Int16 -morebits(::Type{Int16}) = Int32 -morebits(::Type{Int32}) = Int64 -morebits(::Type{Int64}) = Int128 -morebits(::Type{Uint8}) = Uint16 -morebits(::Type{Uint16}) = Uint32 -morebits(::Type{Uint32}) = Uint64 -morebits(::Type{Uint64}) = Uint128 +widen(::Type{Int8}) = Int +widen(::Type{Int16}) = Int +widen(::Type{Int32}) = Int64 +widen(::Type{Int64}) = Int128 +widen(::Type{Uint8}) = Uint +widen(::Type{Uint16}) = Uint +widen(::Type{Uint32}) = Uint64 +widen(::Type{Uint64}) = Uint128 ## float to integer coercion ## diff --git a/base/mpfr.jl b/base/mpfr.jl index 5ab7b2288a5d1..c2ab9b10a72d5 100644 --- a/base/mpfr.jl +++ b/base/mpfr.jl @@ -17,7 +17,7 @@ import itrunc, eps, signbit, sin, cos, tan, sec, csc, cot, acos, asin, atan, cosh, sinh, tanh, sech, csch, coth, acosh, asinh, atanh, atan2, serialize, deserialize, inf, nan, hash, cbrt, typemax, typemin, - realmin, realmax, get_rounding, set_rounding, maxintfloat + realmin, realmax, get_rounding, set_rounding, maxintfloat, widen import Base.Math.lgamma_r @@ -44,6 +44,9 @@ type BigFloat <: FloatingPoint end end +widen(::Type{Float64}) = BigFloat +widen(::Type{BigFloat}) = BigFloat + BigFloat(x::BigFloat) = x for (fJ, fC) in ((:si,:Clong), (:ui,:Culong), (:d,:Float64)) diff --git a/base/operators.jl b/base/operators.jl index 018598b38201b..598284fe43ecd 100644 --- a/base/operators.jl +++ b/base/operators.jl @@ -146,6 +146,8 @@ oftype{T}(x::T,c) = convert(T,c) zero(x) = oftype(x,0) one(x) = oftype(x,1) +widen{T<:Number}(x::T) = convert(widen(T), x) + sizeof(T::Type) = error(string("size of type ",T," unknown")) sizeof(T::DataType) = if isleaftype(T) T.size else error("type does not have a native size") end sizeof(::Type{Symbol}) = error("type does not have a native size") diff --git a/doc/stdlib/base.rst b/doc/stdlib/base.rst index 9af5bfceff3de..d4a035a3ab688 100644 --- a/doc/stdlib/base.rst +++ b/doc/stdlib/base.rst @@ -231,6 +231,15 @@ All Objects Convert ``y`` to the type of ``x``. +.. function:: widen(type | x) + + If the argument is a type, return a "larger" type (for numeric types, this will be + a type with at least as much range and precision as the argument, and usually more). + Otherwise the argument ``x`` is converted to ``widen(typeof(x))``. + + **Example**: ``widen(Int32) === Int64`` + **Example**: ``widen(1.5f0) === 1.5`` + .. function:: identity(x) The identity function. Returns its argument. diff --git a/test/numbers.jl b/test/numbers.jl index ab2cf8a5d00dc..50061c410b785 100644 --- a/test/numbers.jl +++ b/test/numbers.jl @@ -1763,3 +1763,12 @@ end let g(x) = sqrt(x) @test g(NaN) === NaN end + +# widen +@test widen(1.5f0) === 1.5 +@test widen(int32(42)) === int64(42) +@test widen(Int8) === Int +@test widen(Float32) === Float64 +## Note: this should change to e.g. Float128 at some point +@test widen(Float64) === BigFloat +@test widen(BigInt) === BigInt