Skip to content

Commit

Permalink
also export widemul (ref #6169)
Browse files Browse the repository at this point in the history
widen methods for Rational and Complex
  • Loading branch information
JeffBezanson committed Mar 15, 2014
1 parent a953172 commit ce3f003
Show file tree
Hide file tree
Showing 9 changed files with 15 additions and 14 deletions.
3 changes: 2 additions & 1 deletion NEWS.md
Original file line number Diff line number Diff line change
Expand Up @@ -221,7 +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])
* New function `widen` for widening numeric types and values, and `widemul`
for multiplying to a larger type ([#6169])

Deprecated or removed
---------------------
Expand Down
2 changes: 2 additions & 0 deletions base/complex.jl
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ promote_rule{T<:Real,S<:Real}(::Type{Complex{T}}, ::Type{S}) =
promote_rule{T<:Real,S<:Real}(::Type{Complex{T}}, ::Type{Complex{S}}) =
Complex{promote_type(T,S)}

widen{T}(::Type{Complex{T}}) = Complex{widen(T)}

real(z::Complex) = z.re
imag(z::Complex) = z.im
real(x::Real) = x
Expand Down
1 change: 1 addition & 0 deletions base/exports.jl
Original file line number Diff line number Diff line change
Expand Up @@ -448,6 +448,7 @@ export
uint64,
uint8,
unsigned,
widemul,
zero,

# specfun
Expand Down
2 changes: 0 additions & 2 deletions base/gmp.jl
Original file line number Diff line number Diff line change
Expand Up @@ -412,10 +412,8 @@ ndigits(x::BigInt, b::Integer=10) = x.size == 0 ? 1 : ndigits0z(x,b)

isprime(x::BigInt, reps=25) = ccall((:__gmpz_probab_prime_p,:libgmp), Cint, (Ptr{BigInt}, Cint), &x, reps) > 0

widemul(x::BigInt, y::BigInt) = x*y
widemul(x::Int128, y::Uint128) = BigInt(x)*BigInt(y)
widemul(x::Uint128, y::Int128) = BigInt(x)*BigInt(y)
widemul{T<:Integer}(x::T, y::T) = BigInt(x)*BigInt(y)

prevpow2(x::BigInt) = x.size < 0 ? -prevpow2(-x) : (x <= 2 ? x : one(BigInt) << (ndigits(x, 2)-1))
nextpow2(x::BigInt) = x.size < 0 ? -nextpow2(-x) : (x <= 2 ? x : one(BigInt) << ndigits(x-1, 2))
Expand Down
11 changes: 0 additions & 11 deletions base/int.jl
Original file line number Diff line number Diff line change
Expand Up @@ -486,14 +486,6 @@ end

## wide multiplication, Int128 multiply and divide ##

widemul(x::Union(Int8,Uint8,Int16), y::Union(Int8,Uint8,Int16)) = int32(x)*int32(y)
widemul(x::Uint16, y::Uint16) = uint32(x)*uint32(y)

widemul(x::Int32, y::Int32) = int64(x)*int64(y)
widemul(x::Uint32, y::Uint32) = uint64(x)*uint64(y)

widemul(x::Integer, y::Integer) = widemul(promote(x,y)...)

if WORD_SIZE==32
function widemul(u::Int64, v::Int64)
local u0::Uint64, v0::Uint64, w0::Uint64
Expand Down Expand Up @@ -564,9 +556,6 @@ if WORD_SIZE==32
>>>(x::Int128, y::Int32) = y == 0 ? x : box(Int128,lshr_int(unbox(Int128,x),unbox(Int32,y)))
>>>(x::Uint128, y::Int32) = y == 0 ? x : box(Uint128,lshr_int(unbox(Uint128,x),unbox(Int32,y)))
else
widemul(u::Int64, v::Int64) = int128(u)*int128(v)
widemul(u::Uint64, v::Uint64) = uint128(u)*uint128(v)

*(x::Int128, y::Int128) = box(Int128,mul_int(unbox(Int128,x),unbox(Int128,y)))
*(x::Uint128, y::Uint128) = box(Uint128,mul_int(unbox(Uint128,x),unbox(Uint128,y)))

Expand Down
2 changes: 2 additions & 0 deletions base/number.jl
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ ctranspose(x::Number) = conj(x)
inv(x::Number) = one(x)/x
angle(z::Real) = atan2(zero(z), z)

widemul(x::Number, y::Number) = widen(x)*widen(y)

start(x::Number) = false
next(x::Number, state) = (x, true)
done(x::Number, state) = state
Expand Down
2 changes: 2 additions & 0 deletions base/rational.jl
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,8 @@ promote_rule{T<:Integer,S<:Integer}(::Type{Rational{T}}, ::Type{S}) = Rational{p
promote_rule{T<:Integer,S<:Integer}(::Type{Rational{T}}, ::Type{Rational{S}}) = Rational{promote_type(T,S)}
promote_rule{T<:Integer,S<:FloatingPoint}(::Type{Rational{T}}, ::Type{S}) = promote_type(T,S)

widen{T}(::Type{Rational{T}}) = Rational{widen(T)}

function rationalize{T<:Integer}(::Type{T}, x::FloatingPoint; tol::Real=eps(x))
if isnan(x); return zero(T)//zero(T); end
if x < typemin(T); return -one(T)//zero(T); end
Expand Down
4 changes: 4 additions & 0 deletions doc/stdlib/base.rst
Original file line number Diff line number Diff line change
Expand Up @@ -3008,6 +3008,10 @@ Mathematical Functions

Compute the number of digits in number ``n`` written in base ``b``.

.. function:: widemul(x, y)

Multiply ``x`` and ``y``, giving the result as a larger type.

Data Formats
------------

Expand Down
2 changes: 2 additions & 0 deletions test/numbers.jl
Original file line number Diff line number Diff line change
Expand Up @@ -1772,3 +1772,5 @@ end
## Note: this should change to e.g. Float128 at some point
@test widen(Float64) === BigFloat
@test widen(BigInt) === BigInt

@test widemul(typemax(Int64),typemax(Int64)) == 85070591730234615847396907784232501249

0 comments on commit ce3f003

Please sign in to comment.