1- const UIntStorage = Union{UInt8,UInt16,UInt32,UInt64,UInt128}
1+ const UIntStorage = Union{UInt8,UInt16,UInt32,UInt64,UInt128,LongLongUInt }
22const IntStorage = Union{Int8,Int16,Int32,Int64,Int128,BigInt,UIntStorage}
33
44# ######### DitStr #########
@@ -37,23 +37,27 @@ function DitStr{D,T}(vector::Union{AbstractVector,Tuple}) where {D,T}
3737 val = zero (T)
3838 D_power_k = one (T)
3939 for k in 1 : length (vector)
40- 0 <= vector[k] <= D- 1 || error (" expect 0 or 1 , got $(vector[k]) " )
41- val += vector[k] * D_power_k
42- D_power_k *= D
40+ 0 <= vector[k] <= D- 1 || error (" expect 0- $(D - 1 ) , got $(vector[k]) " )
41+ val = accum ( Val {D} (), val, vector[k], D_power_k)
42+ D_power_k = _lshift ( Val {D} (), D_power_k, 1 )
4343 end
4444 return DitStr {D,length(vector),T} (val)
4545end
46+ # val += x * y
47+ accum (:: Val{D} , val, x, y) where D = val + x * y
48+ accum (:: Val{2} , val, x, y) = iszero (x) ? val : val ⊻ y
4649DitStr {D} (vector:: Tuple{T,Vararg{T,N}} ) where {N,T,D} = DitStr {D,T} (vector)
4750DitStr {D} (vector:: AbstractVector{T} ) where {D,T} = DitStr {D,T} (vector)
4851DitStr {D,N,T} (val:: DitStr ) where {D,N,T<: Integer } = convert (DitStr{D,N,T}, val)
4952DitStr {D,N,T} (val:: DitStr{D,N,T} ) where {D,N,T<: Integer } = val
5053
5154const DitStr64{D,N} = DitStr{D,N,Int64}
52- const LongDitStr{D,N} = DitStr{D,N,BigInt}
55+ const LongDitStr{D,N} = DitStr{D,N,LongLongUInt{C}} where C
56+ LongDitStr {D} (vector:: AbstractVector{T} ) where {D,T} = DitStr {D,longinttype(length(vector), D)} (vector)
5357
5458Base. show (io:: IO , ditstr:: DitStr{D,N,<:Integer} ) where {D,N} =
5559 print (io, string (buffer (ditstr), base = D, pad = N), " ₍$(' ₀' + D) ₎" )
56- Base. show (io:: IO , ditstr:: DitStr{D,N,<:BigInt } ) where {D,N} =
60+ Base. show (io:: IO , ditstr:: DitStr{D,N,<:LongLongUInt } ) where {D,N} =
5761 print (io, join (map (string, [ditstr[end : - 1 : 1 ]. .. ])), " ₍$(' ₀' + D) ₎" )
5862
5963Base. zero (:: Type{DitStr{D,N,T}} ) where {D,N,T} = DitStr {D,N,T} (zero (T))
@@ -295,20 +299,29 @@ function parse_dit(::Type{T}, str::String) where {T<:Integer}
295299end
296300
297301function _parse_dit (:: Val{D} , :: Type{T} , str:: AbstractString ) where {D, T<: Integer }
302+ TT = T <: LongLongUInt ? longinttype (count (isdigit, str), D) : T
303+ _parse_dit_safe (Val (D), TT, str)
304+ end
305+
306+ function _parse_dit_safe (:: Val{D} , :: Type{T} , str:: AbstractString ) where {D, T<: Integer }
298307 val = zero (T)
299- k = 1
300- maxk = T <: BigInt ? Inf : log ( typemax (T)) / log ( D)
308+ k = 0
309+ maxk = max_num_elements (T, D)
301310 for each in reverse (str)
302- k >= maxk && error (" string length is larger than $(maxk) , use @ldit_str instead" )
311+ k >= maxk- 1 && error (" string length is larger than $(maxk) , use @ldit_str instead" )
303312 v = each - ' 0'
304313 if 0 <= v < D
305- val += _lshift (Val (D), v , k- 1 )
314+ val += _lshift (Val (D), T (v) , k)
306315 k += 1
307316 elseif each == ' _'
308317 continue
309318 else
310- error (" expect char in range 0-$(D- 1 ) , got $each at $k -th dit" )
319+ error (" expect char in range 0-$(D- 1 ) , got $each at $(k + 1 ) -th dit" )
311320 end
312321 end
313- return DitStr {D,k-1 ,T} (val)
322+ return DitStr {D,k,T} (val)
314323end
324+
325+ max_num_elements (:: Type{T} , D:: Int ) where T<: Integer = floor (Int, log (typemax (T))/ log (D))
326+ max_num_elements (:: Type{BigInt} , D:: Int ) = typemax (Int)
327+ max_num_elements (:: Type{LongLongUInt{C}} , D:: Int ) where {C} = max_num_elements (UInt, D) * C
0 commit comments