@@ -3,6 +3,23 @@ module DecFP
33
44using Compat, Compat. Printf, Compat. Unicode
55
6+ # When Compat PR #491 is merged, REQUIRE that version and delete this
7+ # 0.7.0-DEV.3469
8+ @static if ! isdefined (Base, :GC )
9+ @eval module GC
10+ using Base: gc
11+ const enable = Base. gc_enable
12+ @static if ! isdefined (Base, Symbol (" @gc_preserve" ))
13+ macro preserve (args... )
14+ esc (args[end ])
15+ end
16+ else
17+ @eval const $ (Symbol (" @preserve" )) = Base.$ (Symbol (" @gc_preserve" ))
18+ end
19+ end
20+ export GC
21+ end
22+
623export Dec32, Dec64, Dec128, @d_str , @d32_str , @d64_str , @d128_str
724
825const libbid = joinpath (dirname (@__FILE__ ), " .." , " deps" , " libbid$(Sys. WORD_SIZE) " )
@@ -71,14 +88,6 @@ function isnanstr(s::AbstractString)
7188 return true
7289end
7390
74- function Base. show (io:: IO , x:: DecimalFloatingPoint )
75- s = @sprintf (" %g" , x)
76- if contains (s, r" ^-?\d +$" )
77- s *= " .0"
78- end
79- print (io, s)
80- end
81-
8291for w in (32 ,64 ,128 )
8392 BID = Symbol (string (" Dec" ,w))
8493 Ti = eval (Symbol (string (" UInt" ,w)))
@@ -105,6 +114,62 @@ for w in (32,64,128)
105114
106115 $ BID (x:: AbstractString ) = parse ($ BID, x)
107116
117+ function Base. show (io:: IO , x:: $BID )
118+ isnan (x) && (write (io, " NaN" ); return )
119+ isinf (x) && (write (io, signbit (x) ? " -Inf" : " Inf" ); return )
120+ x == 0 && (write (io, signbit (x) ? " -0.0" : " 0.0" ); return )
121+ ccall (($ (bidsym (w," to_string" )), libbid), Cvoid, (Ptr{UInt8}, $ BID), _buffer, x)
122+ if _buffer[1 ] == UInt8 (' -' )
123+ write (io, ' -' )
124+ end
125+ normalized_exponent = nox (ccall (($ (bidsym (w," ilogb" )), libbid), Cint, ($ BID,), x))
126+ lastdigitindex = Compat. findfirst (equalto (UInt8 (' E' )), _buffer) - 1
127+ lastnonzeroindex = Compat. findlast (! equalto (UInt8 (' 0' )), view (_buffer, 1 : lastdigitindex))
128+ if - 5 < normalized_exponent < 6
129+ # %f
130+ if normalized_exponent >= 0
131+ if normalized_exponent >= lastnonzeroindex - 2
132+ GC. @preserve _buffer unsafe_write (io, pointer (_buffer, 2 ), lastnonzeroindex - 1 )
133+ writezeros (io, normalized_exponent - lastnonzeroindex + 2 )
134+ write (io, " .0" )
135+ else
136+ GC. @preserve _buffer unsafe_write (io, pointer (_buffer, 2 ), normalized_exponent + 1 )
137+ write (io, ' .' )
138+ GC. @preserve _buffer unsafe_write (io, pointer (_buffer, normalized_exponent + 3 ), lastnonzeroindex - normalized_exponent - 2 )
139+ end
140+ else
141+ write (io, " 0." )
142+ writezeros (io, - normalized_exponent - 1 )
143+ GC. @preserve _buffer unsafe_write (io, pointer (_buffer, 2 ), lastnonzeroindex - 1 )
144+ end
145+ else
146+ # %e
147+ write (io, _buffer[2 ], ' .' )
148+ if lastnonzeroindex == 2
149+ write (io, ' 0' )
150+ else
151+ GC. @preserve _buffer unsafe_write (io, pointer (_buffer, 3 ), lastnonzeroindex - 2 )
152+ end
153+ write (io, ' e' )
154+ if normalized_exponent < 0
155+ write (io, ' -' )
156+ normalized_exponent = - normalized_exponent
157+ end
158+ b_lb = div (normalized_exponent, 10 )
159+ b = 1
160+ while b <= b_lb
161+ b *= 10
162+ end
163+ r = normalized_exponent
164+ while b > 0
165+ q, r = divrem (r, b)
166+ write (io, UInt8 (' 0' ) + (q% UInt8))
167+ b = div (b, 10 )
168+ end
169+ end
170+ return
171+ end
172+
108173 function Base. Printf. fix_dec (x:: $BID , n:: Int )
109174 if n > length (DIGITS) - 1
110175 n = length (DIGITS) - 1
@@ -369,4 +434,10 @@ function xchk(x, exc::Type{E}, args...; mask::Integer=0x3f) where {E<:Exception}
369434 return x
370435end
371436
437+ function writezeros (io:: IO , n:: Int )
438+ for i = 1 : n
439+ write (io, UInt8 (' 0' ))
440+ end
441+ end
442+
372443end # module
0 commit comments