@@ -150,9 +150,8 @@ cdef numeric_decode_binary_ex(
150
150
int64_t abs_exponent
151
151
ssize_t exponent_chars
152
152
ssize_t front_padding = 0
153
- ssize_t trailing_padding = 0
154
153
ssize_t num_fract_digits
155
- ssize_t dscale_left
154
+ ssize_t trailing_fract_zeros_adj
156
155
char smallbuf[_NUMERIC_DECODER_SMALLBUF_SIZE]
157
156
char * charbuf
158
157
char * bufptr
@@ -175,14 +174,34 @@ cdef numeric_decode_binary_ex(
175
174
elif pgdigit0 < 1000 :
176
175
front_padding = 1
177
176
177
+ # The number of fractional decimal digits actually encoded in
178
+ # base-DEC_DEIGITS digits sent by Postgres.
179
+ num_fract_digits = (num_pgdigits - weight - 1 ) * DEC_DIGITS
180
+
181
+ # The trailing zero adjustment necessary to obtain exactly
182
+ # dscale number of fractional digits in output. May be negative,
183
+ # which indicates that trailing zeros in the last input digit
184
+ # should be discarded.
185
+ trailing_fract_zeros_adj = dscale - num_fract_digits
186
+
178
187
# Maximum possible number of decimal digits in base 10.
179
- num_pydigits = num_pgdigits * DEC_DIGITS + dscale
188
+ # The actual number might be up to 3 digits smaller due to
189
+ # leading zeros in first input digit.
190
+ num_pydigits = num_pgdigits * DEC_DIGITS
191
+ if trailing_fract_zeros_adj > 0 :
192
+ num_pydigits += trailing_fract_zeros_adj
193
+
180
194
# Exponent.
181
195
exponent = (weight + 1 ) * DEC_DIGITS - front_padding
182
196
abs_exponent = abs (exponent)
183
- # Number of characters required to render absolute exponent value.
184
- exponent_chars = < ssize_t> log10(< double > abs_exponent) + 1
197
+ if abs_exponent != 0 :
198
+ # Number of characters required to render absolute exponent value
199
+ # in decimal.
200
+ exponent_chars = < ssize_t> log10(< double > abs_exponent) + 1
201
+ else :
202
+ exponent_chars = 0
185
203
204
+ # Output buffer size.
186
205
buf_size = (
187
206
1 + # sign
188
207
1 + # leading zero
@@ -221,21 +240,14 @@ cdef numeric_decode_binary_ex(
221
240
bufptr = _unpack_digit(bufptr, pgdigit)
222
241
223
242
if dscale:
224
- if weight >= 0 :
225
- num_fract_digits = num_pgdigits - weight - 1
226
- else :
227
- num_fract_digits = num_pgdigits
228
-
229
- # Check how much dscale is left to render (trailing zeros).
230
- dscale_left = dscale - num_fract_digits * DEC_DIGITS
231
- if dscale_left > 0 :
232
- for i in range (dscale_left):
243
+ if trailing_fract_zeros_adj > 0 :
244
+ for i in range (trailing_fract_zeros_adj):
233
245
bufptr[i] = < char > b' 0'
234
246
235
247
# If display scale is _less_ than the number of rendered digits,
236
- # dscale_left will be negative and this will strip the excess
237
- # trailing zeros.
238
- bufptr += dscale_left
248
+ # trailing_fract_zeros_adj will be negative and this will strip
249
+ # the excess trailing zeros.
250
+ bufptr += trailing_fract_zeros_adj
239
251
240
252
if trail_fract_zero:
241
253
# Check if the number of rendered digits matches the exponent,
0 commit comments