@@ -6,6 +6,7 @@ const libbid = joinpath(dirname(@__FILE__), "..", "deps", "libbid$(Sys.WORD_SIZE
66const _buffer = Vector {UInt8} (1024 )
77
88import Base. promote_rule
9+ import Base. Grisu. DIGITS
910
1011# https://github.com/JuliaLang/julia/pull/20005
1112if VERSION < v " 0.7.0-DEV.896"
@@ -102,11 +103,80 @@ for w in (32,64,128)
102103 return xchk (x, InexactError, :parse , $ BID, s)
103104 end
104105
106+ $ BID (x:: AbstractString ) = parse ($ BID, x)
107+
105108 function Base. show (io:: IO , x:: $BID )
106109 ccall (($ (bidsym (w," to_string" )), libbid), Void, (Ptr{UInt8}, $ BID), _buffer, x)
107110 unsafe_write (io, pointer (_buffer), ccall (:strlen , Csize_t, (Ptr{UInt8},), _buffer))
108111 end
109112
113+ function Base. Printf. fix_dec (x:: $BID , n:: Int )
114+ if n > length (DIGITS) - 1
115+ n = length (DIGITS) - 1
116+ end
117+ # rounded = round(x * exp10($BID(n)), RoundNearestTiesAway)
118+ rounded = xchk (ccall (($ (bidsym (w," round_integral_nearest_away" )), libbid), $ BID, ($ BID,), x * exp10 ($ BID (n))), InexactError, :round , $ BID, x, mask= INVALID | OVERFLOW)
119+ if rounded == 0
120+ DIGITS[1 ] = UInt8 (' 0' )
121+ return Int32 (1 ), Int32 (1 ), signbit (x)
122+ end
123+ ccall (($ (bidsym (w," to_string" )), libbid), Void, (Ptr{UInt8}, $ BID), _buffer, rounded)
124+ trailing_zeros = 0
125+ i = 2
126+ while _buffer[i] != UInt8 (' E' )
127+ DIGITS[i - 1 ] = _buffer[i]
128+ if _buffer[i] == UInt8 (' 0' )
129+ trailing_zeros += 1
130+ else
131+ trailing_zeros = 0
132+ end
133+ i += 1
134+ end
135+ ndigits = i - 2
136+ len = ndigits - trailing_zeros
137+ i += 1
138+ if _buffer[i] == UInt8 (' +' )
139+ expsign = + 1
140+ elseif _buffer[i] == UInt8 (' -' )
141+ expsign = - 1
142+ end
143+ exponent = 0
144+ i += 1
145+ while _buffer[i] != 0x00
146+ exponent = exponent * 10 + _buffer[i] - UInt8 (' 0' )
147+ i += 1
148+ end
149+ exponent *= expsign
150+ pt = ndigits + exponent - n
151+ neg = signbit (x)
152+ return Int32 (len), Int32 (pt), neg
153+ end
154+
155+ function Base. Printf. ini_dec (x:: $BID , n:: Int )
156+ if n > length (DIGITS) - 1
157+ n = length (DIGITS) - 1
158+ end
159+ if x == 0
160+ for i = 1 : n
161+ DIGITS[i] = UInt8 (' 0' )
162+ end
163+ return Int32 (1 ), Int32 (1 ), signbit (x)
164+ end
165+ normalized_exponent = nox (ccall (($ (bidsym (w," ilogb" )), libbid), Cint, ($ BID,), x))
166+ # rounded = round(x * exp10($BID(n - 1 - normalized_exponent)), RoundNearestTiesAway)
167+ rounded = xchk (ccall (($ (bidsym (w," round_integral_nearest_away" )), libbid), $ BID, ($ BID,), x * exp10 ($ BID (n - 1 - normalized_exponent))), InexactError, :round , $ BID, x, mask= INVALID | OVERFLOW)
168+ rounded_exponent = nox (ccall (($ (bidsym (w," ilogb" )), libbid), Cint, ($ BID,), rounded))
169+ ccall (($ (bidsym (w," to_string" )), libbid), Void, (Ptr{UInt8}, $ BID), _buffer, rounded)
170+ i = 2
171+ while _buffer[i] != UInt8 (' E' )
172+ DIGITS[i - 1 ] = _buffer[i]
173+ i += 1
174+ end
175+ pt = normalized_exponent + rounded_exponent - n + 2
176+ neg = signbit (x)
177+ return Int32 (n), Int32 (pt), neg
178+ end
179+
110180 Base. fma (x:: $BID , y:: $BID , z:: $BID ) = nox (ccall (($ (bidsym (w," fma" )), libbid), $ BID, ($ BID,$ BID,$ BID), x, y, z))
111181 Base. muladd (x:: $BID , y:: $BID , z:: $BID ) = fma (x,y,z) # faster than x+y*z
112182
0 commit comments