From e85e0a0ad40abbbe224a14dc2d44c8b7af58ac7a Mon Sep 17 00:00:00 2001 From: "Steven G. Johnson" Date: Fri, 15 Nov 2013 12:46:53 -0500 Subject: [PATCH] add BigInt prevpow2/nextpow2 (fix #4814) --- base/gmp.jl | 6 +++++- test/numbers.jl | 12 ++++++++++++ 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/base/gmp.jl b/base/gmp.jl index cbde9864a09ac..0734e19c87b8a 100644 --- a/base/gmp.jl +++ b/base/gmp.jl @@ -6,7 +6,8 @@ import Base: *, +, -, /, <, <<, >>, >>>, <=, ==, >, >=, ^, (~), (&), (|), ($), binomial, cmp, convert, div, divrem, factorial, fld, gcd, gcdx, lcm, mod, 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 + serialize, deserialize, bin, oct, dec, hex, isequal, invmod, + prevpow2, nextpow2 type BigInt <: Integer alloc::Cint @@ -414,4 +415,7 @@ 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 < 0 ? -prevpow2(-x) : (x <= 2 ? x : one(BigInt) << (ndigits(x, 2)-1)) +nextpow2(x::BigInt) = x < 0 ? -nextpow2(-x) : (x <= 2 ? x : one(BigInt) << ndigits(x-1, 2)) + end # module diff --git a/test/numbers.jl b/test/numbers.jl index 8a849bf203ebe..8c3acbb270a0b 100644 --- a/test/numbers.jl +++ b/test/numbers.jl @@ -1551,3 +1551,15 @@ end # negative power domain error @test_throws powermod(1,-2,1) @test_throws powermod(big(1),-2,1) + +# prevpow2/nextpow2: +@test nextpow2(0) == prevpow2(0) == 0 +for i = -2:2 + @test nextpow2(i) == prevpow2(i) == i +end +@test nextpow2(56789) == -nextpow2(-56789) == 65536 +@test prevpow2(56789) == -prevpow2(-56789) == 32768 +for i = -100:100 + @test nextpow2(i) == nextpow2(big(i)) + @test prevpow2(i) == prevpow2(big(i)) +end