diff --git a/base/intfuncs.jl b/base/intfuncs.jl index 2b75f09ac62e7..a6f6ea05efe41 100644 --- a/base/intfuncs.jl +++ b/base/intfuncs.jl @@ -440,7 +440,8 @@ function ndigits0znb(x::Integer, b::Integer) return d end -ndigits0znb(x::Unsigned, b::Integer) = ndigits0znb(signed(x), b) +# do first division before conversion with signed here, which can otherwise overflow +ndigits0znb(x::Unsigned, b::Integer) = ndigits0znb(-signed(fld(x, -b)), b) + (x != 0) ndigits0znb(x::Bool, b::Integer) = x % Int # The suffix "pb" stands for "positive base" diff --git a/test/intfuncs.jl b/test/intfuncs.jl index 4ead5b224fad0..b060bc69686b2 100644 --- a/test/intfuncs.jl +++ b/test/intfuncs.jl @@ -139,6 +139,15 @@ end @test iszero([Base.ndigits0z(false, b) for b in [-20:-2;2:20]]) @test all(n -> n == 1, Base.ndigits0z(true, b) for b in [-20:-2;2:20]) @test all(n -> n == 1, ndigits(x, base=b) for b in [-20:-2;2:20] for x in [true, false]) + + # issue #29148 + @test ndigits(typemax(UInt64), base=-2) == ndigits(big(typemax(UInt64)), base=-2) + for T in Base.BitInteger_types + n = rand(T) + b = -rand(2:100) + @test ndigits(n, base=b) == ndigits(big(n), base=b) + end + end @testset "bin/oct/dec/hex/bits" begin @test string(UInt32('3'), base = 2) == "110011"