File Coverage

bson/bson-decimal128.c
Criterion Covered Total %
statement 0 291 0.0
branch 0 172 0.0
condition n/a
subroutine n/a
pod n/a
total 0 463 0.0


line stmt bran cond sub pod time code
1              
2             /*
3             * Copyright 2015 MongoDB, Inc.
4             *
5             * Licensed under the Apache License, Version 2.0 (the "License");
6             * you may not use this file except in compliance with the License.
7             * You may obtain a copy of the License at
8             *
9             * http://www.apache.org/licenses/LICENSE-2.0
10             *
11             * Unless required by applicable law or agreed to in writing, software
12             * distributed under the License is distributed on an "AS IS" BASIS,
13             * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14             * See the License for the specific language governing permissions and
15             * limitations under the License.
16             */
17              
18             #include
19             #include
20             #include
21             #include
22              
23             #include "bson-decimal128.h"
24             #include "bson-types.h"
25             #include "bson-macros.h"
26             #include "bson-string.h"
27              
28              
29             #define BSON_DECIMAL128_EXPONENT_MAX 6111
30             #define BSON_DECIMAL128_EXPONENT_MIN -6176
31             #define BSON_DECIMAL128_EXPONENT_BIAS 6176
32             #define BSON_DECIMAL128_MAX_DIGITS 34
33              
34             #define BSON_DECIMAL128_SET_NAN(dec) \
35             do { (dec).high = 0x7c00000000000000ull; (dec).low = 0; } while (0);
36             #define BSON_DECIMAL128_SET_INF(dec, isneg) \
37             do { \
38             (dec).high = 0x7800000000000000ull + 0x8000000000000000ull * (isneg); \
39             (dec).low = 0; \
40             } while (0);
41              
42             /**
43             * _bson_uint128_t:
44             *
45             * This struct represents a 128 bit integer.
46             */
47             typedef struct
48             {
49             uint32_t parts[4]; /* 32-bit words stored high to low. */
50             } _bson_uint128_t;
51              
52              
53             /**
54             *------------------------------------------------------------------------------
55             *
56             * _bson_uint128_divide1B --
57             *
58             * This function divides a #_bson_uint128_t by 1000000000 (1 billion) and
59             * computes the quotient and remainder.
60             *
61             * The remainder will contain 9 decimal digits for conversion to string.
62             *
63             * @value The #_bson_uint128_t operand.
64             * @quotient A pointer to store the #_bson_uint128_t quotient.
65             * @rem A pointer to store the #uint64_t remainder.
66             *
67             * Returns:
68             * The quotient at @quotient and the remainder at @rem.
69             *
70             * Side effects:
71             * None.
72             *
73             *------------------------------------------------------------------------------
74             */
75             static void
76 0           _bson_uint128_divide1B (_bson_uint128_t value, /* IN */
77             _bson_uint128_t *quotient, /* OUT */
78             uint32_t *rem) /* OUT */
79             {
80 0           const uint32_t DIVISOR = 1000 * 1000 * 1000;
81 0           uint64_t _rem = 0;
82 0           int i = 0;
83              
84 0 0         if (!value.parts[0] && !value.parts[1] &&
    0          
    0          
85 0 0         !value.parts[2] && !value.parts[3]) {
86 0           *quotient = value;
87 0           *rem = 0;
88 0           return;
89             }
90              
91              
92 0 0         for (i = 0; i <= 3; i++) {
93 0           _rem <<= 32; /* Adjust remainder to match value of next dividend */
94 0           _rem += value.parts[i]; /* Add the divided to _rem */
95 0           value.parts[i] = (uint32_t)(_rem / DIVISOR);
96 0           _rem %= DIVISOR; /* Store the remainder */
97             }
98              
99 0           *quotient = value;
100 0           *rem = _rem;
101             }
102              
103              
104             /**
105             *------------------------------------------------------------------------------
106             *
107             * bson_decimal128_to_string --
108             *
109             * This function converts a BID formatted decimal128 value to string,
110             * accepting a &bson_decimal128_t as @dec. The string is stored at @str.
111             *
112             * @dec : The BID formatted decimal to convert.
113             * @str : The output decimal128 string. At least %BSON_DECIMAL128_STRING characters.
114             *
115             * Returns:
116             * None.
117             *
118             * Side effects:
119             * None.
120             *
121             *------------------------------------------------------------------------------
122             */
123             void
124 0           bson_decimal128_to_string (const bson_decimal128_t *dec, /* IN */
125             char *str) /* OUT */
126             {
127 0           uint32_t COMBINATION_MASK = 0x1f; /* Extract least significant 5 bits */
128 0           uint32_t EXPONENT_MASK = 0x3fff; /* Extract least significant 14 bits */
129 0           uint32_t COMBINATION_INFINITY = 30; /* Value of combination field for Inf */
130 0           uint32_t COMBINATION_NAN = 31; /* Value of combination field for NaN */
131 0           uint32_t EXPONENT_BIAS = 6176; /* decimal128 exponent bias */
132              
133 0           char *str_out = str; /* output pointer in string */
134             char significand_str[35]; /* decoded significand digits */
135              
136              
137             /* Note: bits in this routine are referred to starting at 0, */
138             /* from the sign bit, towards the coefficient. */
139             uint32_t high; /* bits 0 - 31 */
140             uint32_t midh; /* bits 32 - 63 */
141             uint32_t midl; /* bits 64 - 95 */
142             uint32_t low; /* bits 96 - 127 */
143             uint32_t combination; /* bits 1 - 5 */
144             uint32_t biased_exponent; /* decoded biased exponent (14 bits) */
145 0           uint32_t significand_digits = 0; /* the number of significand digits */
146 0           uint32_t significand[36] = { 0 }; /* the base-10 digits in the significand */
147 0           uint32_t *significand_read = significand; /* read pointer into significand */
148             int32_t exponent; /* unbiased exponent */
149             int32_t scientific_exponent; /* the exponent if scientific notation is
150             * used */
151 0           bool is_zero = false; /* true if the number is zero */
152              
153             uint8_t significand_msb; /* the most signifcant significand bits (50-46) */
154             _bson_uint128_t significand128; /* temporary storage for significand decoding */
155             size_t i; /* indexing variables */
156             int j, k;
157              
158 0           memset (significand_str, 0, sizeof (significand_str));
159              
160 0 0         if ((int64_t)dec->high < 0) { /* negative */
161 0           *(str_out++) = '-';
162             }
163              
164 0           low = (uint32_t)dec->low,
165 0           midl = (uint32_t)(dec->low >> 32),
166 0           midh = (uint32_t)dec->high,
167 0           high = (uint32_t)(dec->high >> 32);
168              
169             /* Decode combination field and exponent */
170 0           combination = (high >> 26) & COMBINATION_MASK;
171              
172 0 0         if (BSON_UNLIKELY ((combination >> 3) == 3)) {
173             /* Check for 'special' values */
174 0 0         if (combination == COMBINATION_INFINITY) { /* Infinity */
175 0           strcpy (str_out, "Inf");
176 0           return;
177 0 0         } else if (combination == COMBINATION_NAN) { /* NaN */
178             /* str, not str_out, to erase the sign */
179 0           strcpy (str, "NaN");
180             /* we don't care about the NaN payload. */
181 0           return;
182             } else {
183 0           biased_exponent = (high >> 15) & EXPONENT_MASK;
184 0           significand_msb = 0x8 + ((high >> 14) & 0x1);
185             }
186             } else {
187 0           significand_msb = (high >> 14) & 0x7;
188 0           biased_exponent = (high >> 17) & EXPONENT_MASK;
189             }
190              
191 0           exponent = biased_exponent - EXPONENT_BIAS;
192             /* Create string of significand digits */
193              
194             /* Convert the 114-bit binary number represented by */
195             /* (high, midh, midl, low) to at most 34 decimal */
196             /* digits through modulo and division. */
197 0           significand128.parts[0] = (high & 0x3fff) + ((significand_msb & 0xf) << 14);
198 0           significand128.parts[1] = midh;
199 0           significand128.parts[2] = midl;
200 0           significand128.parts[3] = low;
201              
202 0 0         if (significand128.parts[0] == 0 && significand128.parts[1] == 0 &&
    0          
    0          
203 0 0         significand128.parts[2] == 0 && significand128.parts[3] == 0) {
204 0           is_zero = true;
205 0 0         } else if (significand128.parts[0] >= (1 << 17)) {
206             /* The significand is non-canonical or zero.
207             * In order to preserve compatability with the densely packed decimal
208             * format, the maximum value for the significand of decimal128 is
209             * 1e34 - 1. If the value is greater than 1e34 - 1, the IEEE 754
210             * standard dictates that the significand is interpreted as zero.
211             */
212 0           is_zero = true;
213             } else {
214 0 0         for (k = 3; k >= 0; k--) {
215 0           uint32_t least_digits = 0;
216 0           _bson_uint128_divide1B (significand128, &significand128,
217             &least_digits);
218              
219             /* We now have the 9 least significant digits (in base 2). */
220             /* Convert and output to string. */
221 0 0         if (!least_digits) { continue; }
222              
223 0 0         for (j = 8; j >= 0; j--) {
224 0           significand[k * 9 + j] = least_digits % 10;
225 0           least_digits /= 10;
226             }
227             }
228             }
229              
230             /* Output format options: */
231             /* Scientific - [-]d.dddE(+/-)dd or [-]dE(+/-)dd */
232             /* Regular - ddd.ddd */
233              
234 0 0         if (is_zero) {
235 0           significand_digits = 1;
236 0           *significand_read = 0;
237             } else {
238 0           significand_digits = 36;
239 0 0         while (!(*significand_read)) {
240 0           significand_digits--;
241 0           significand_read++;
242             }
243             }
244              
245 0           scientific_exponent = significand_digits - 1 + exponent;
246              
247             /* The scientific exponent checks are dictated by the string conversion
248             * specification and are somewhat arbitrary cutoffs.
249             *
250             * We must check exponent > 0, because if this is the case, the number
251             * has trailing zeros. However, we *cannot* output these trailing zeros,
252             * because doing so would change the precision of the value, and would
253             * change stored data if the string converted number is round tripped.
254             */
255 0 0         if (scientific_exponent < -6 || exponent > 0) {
    0          
256             /* Scientific format */
257 0           *(str_out++) = *(significand_read++) + '0';
258 0           significand_digits--;
259              
260 0 0         if (significand_digits) {
261 0           *(str_out++) = '.';
262             }
263              
264 0 0         for (i = 0; i < significand_digits; i++) {
265 0           *(str_out++) = *(significand_read++) + '0';
266             }
267             /* Exponent */
268 0           *(str_out++) = 'E';
269 0           bson_snprintf (str_out, 6, "%+d", scientific_exponent);
270             } else {
271             /* Regular format with no decimal place */
272 0 0         if (exponent >= 0) {
273 0 0         for (i = 0; i < significand_digits; i++) {
274 0           *(str_out++) = *(significand_read++) + '0';
275             }
276 0           *str_out = '\0';
277             } else {
278 0           int32_t radix_position = significand_digits + exponent;
279              
280 0 0         if (radix_position > 0) { /* non-zero digits before radix */
281 0 0         for (i = 0; i < radix_position; i++) {
282 0           *(str_out++) = *(significand_read++) + '0';
283             }
284             } else { /* leading zero before radix point */
285 0           *(str_out++) = '0';
286             }
287              
288 0           *(str_out++) = '.';
289 0 0         while (radix_position++ < 0) { /* add leading zeros after radix */
290 0           *(str_out++) = '0';
291             }
292              
293 0 0         for (i = 0; i < significand_digits - BSON_MAX (radix_position - 1, 0);
294 0           i++) {
295 0           *(str_out++) = *(significand_read++) + '0';
296             }
297 0           *str_out = '\0';
298             }
299             }
300             }
301              
302              
303             typedef struct
304             {
305             uint64_t high,
306             low;
307             } _bson_uint128_6464_t;
308              
309              
310             /**
311             *-------------------------------------------------------------------------
312             *
313             * mul64x64 --
314             *
315             * This function multiplies two &uint64_t into a &_bson_uint128_6464_t.
316             *
317             * Returns:
318             * The product of @left and @right.
319             *
320             * Side Effects:
321             * None.
322             *
323             *-------------------------------------------------------------------------
324             */
325             static void
326 0           _mul_64x64 (uint64_t left, /* IN */
327             uint64_t right, /* IN */
328             _bson_uint128_6464_t *product) /* OUT */
329             {
330             uint64_t left_high, left_low,
331             right_high, right_low,
332             product_high, product_mid, product_mid2, product_low;
333 0           _bson_uint128_6464_t rt = { 0 };
334              
335 0 0         if (!left && !right) {
    0          
336 0           *product = rt;
337 0           return;
338             }
339              
340 0           left_high = left >> 32;
341 0           left_low = (uint32_t)left;
342 0           right_high = right >> 32;
343 0           right_low = (uint32_t)right;
344              
345 0           product_high = left_high * right_high;
346 0           product_mid = left_high * right_low;
347 0           product_mid2 = left_low * right_high;
348 0           product_low = left_low * right_low;
349              
350 0           product_high += product_mid >> 32;
351 0           product_mid = (uint32_t)product_mid + product_mid2 + (product_low >> 32);
352              
353 0           product_high = product_high + (product_mid >> 32);
354 0           product_low = (product_mid << 32) + (uint32_t)product_low;
355              
356 0           rt.high = product_high;
357 0           rt.low = product_low;
358 0           *product = rt;
359             }
360              
361             /**
362             *------------------------------------------------------------------------------
363             *
364             * _dec128_tolower --
365             *
366             * This function converts the ASCII character @c to lowercase. It is locale
367             * insensitive (unlike the stdlib tolower).
368             *
369             * Returns:
370             * The lowercased character.
371             */
372             char
373 0           _dec128_tolower (char c)
374             {
375 0 0         if (isupper (c)) {
376 0           c += 32;
377             }
378              
379 0           return c;
380             }
381              
382             /**
383             *------------------------------------------------------------------------------
384             *
385             * _dec128_istreq --
386             *
387             * This function compares the null-terminated *ASCII* strings @a and @b
388             * for case-insensitive equality.
389             *
390             * Returns:
391             * true if the strings are equal, false otherwise.
392             */
393             bool
394 0           _dec128_istreq (const char *a, /* IN */
395             const char *b /* IN */)
396             {
397 0 0         while (*a != '\0' || *b != '\0') {
    0          
398             /* strings are different lengths. */
399 0 0         if (*a == '\0' || *b == '\0') {
    0          
400 0           return false;
401             }
402              
403 0 0         if (_dec128_tolower (*a) != _dec128_tolower (*b)) {
404 0           return false;
405             }
406              
407 0           a++;
408 0           b++;
409             }
410              
411 0           return true;
412             }
413              
414             /**
415             *------------------------------------------------------------------------------
416             *
417             * bson_decimal128_from_string --
418             *
419             * This function converts @string in the format [+-]ddd[.]ddd[E][+-]dddd to
420             * decimal128. Out of range values are converted to +/-Infinity. Invalid
421             * strings are converted to NaN.
422             *
423             * If more digits are provided than the available precision allows,
424             * round to the nearest expressable decimal128 with ties going to even will
425             * occur.
426             *
427             * Note: @string must be ASCII only!
428             *
429             * Returns:
430             * true on success, or false on failure. @dec will be NaN if @str was invalid
431             * The &bson_decimal128_t converted from @string at @dec.
432             *
433             * Side effects:
434             * None.
435             *
436             *------------------------------------------------------------------------------
437             */
438             bool
439 0           bson_decimal128_from_string (const char *string, /* IN */
440             bson_decimal128_t *dec) /* OUT */
441             {
442 0           _bson_uint128_6464_t significand = { 0 };
443              
444 0           const char *str_read = string; /* Read pointer for consuming str. */
445              
446             /* Parsing state tracking */
447 0           bool is_negative = false;
448 0           bool saw_radix = false;
449 0           bool includes_sign = false; /* True if the input string contains a sign. */
450 0           bool found_nonzero = false;
451              
452 0           size_t significant_digits = 0; /* Total number of significant digits
453             * (no leading or trailing zero) */
454 0           size_t ndigits_read = 0; /* Total number of significand digits read */
455 0           size_t ndigits = 0; /* Total number of digits (no leading zeros) */
456 0           size_t radix_position = 0; /* The number of the digits after radix */
457 0           size_t first_nonzero = 0; /* The index of the first non-zero in *str* */
458              
459 0           uint16_t digits[BSON_DECIMAL128_MAX_DIGITS] = { 0 };
460 0           uint16_t ndigits_stored = 0; /* The number of digits in digits */
461 0           uint16_t *digits_insert = digits; /* Insertion pointer for digits */
462 0           size_t first_digit = 0; /* The index of the first non-zero digit */
463 0           size_t last_digit = 0; /* The index of the last digit */
464              
465 0           int32_t exponent = 0;
466 0           size_t i = 0; /* loop index over array */
467 0           uint64_t significand_high = 0; /* The high 17 digits of the significand */
468 0           uint64_t significand_low = 0; /* The low 17 digits of the significand */
469 0           uint16_t biased_exponent = 0; /* The biased exponent */
470              
471 0 0         BSON_ASSERT (dec);
472 0           dec->high = 0;
473 0           dec->low = 0;
474              
475 0 0         if (*str_read == '+' || *str_read == '-') {
    0          
476 0           is_negative = *(str_read++) == '-';
477 0           includes_sign = true;
478             }
479              
480             /* Check for Infinity or NaN */
481 0 0         if (!isdigit (*str_read) && *str_read != '.') {
    0          
482 0           if (_dec128_istreq (str_read, "inf") ||
483 0           _dec128_istreq (str_read, "infinity")) {
484 0           BSON_DECIMAL128_SET_INF (*dec, is_negative);
485 0           return true;
486 0 0         } else if (_dec128_istreq (str_read, "nan")) {
487 0           BSON_DECIMAL128_SET_NAN (*dec);
488 0           return true;
489             }
490              
491 0           BSON_DECIMAL128_SET_NAN (*dec);
492 0           return false;
493             }
494              
495             /* Read digits */
496 0 0         while (isdigit (*str_read) || *str_read == '.') {
    0          
497 0 0         if (*str_read == '.') {
498 0 0         if (saw_radix) {
499 0           BSON_DECIMAL128_SET_NAN (*dec);
500 0           return false;
501             }
502              
503 0           saw_radix = true;
504 0           str_read++;
505 0           continue;
506             }
507              
508 0 0         if (ndigits_stored < 34) {
509 0 0         if (*str_read != '0' || found_nonzero) {
    0          
510 0 0         if (!found_nonzero) {
511 0           first_nonzero = ndigits_read;
512             }
513              
514 0           found_nonzero = true;
515 0           *(digits_insert++) = *(str_read) - '0'; /* Only store 34 digits */
516 0           ndigits_stored++;
517             }
518             }
519              
520 0 0         if (found_nonzero) {
521 0           ndigits++;
522             }
523              
524 0 0         if (saw_radix) {
525 0           radix_position++;
526             }
527              
528 0           ndigits_read++;
529 0           str_read++;
530             }
531              
532 0 0         if (saw_radix && !ndigits_read) {
    0          
533 0           BSON_DECIMAL128_SET_NAN (*dec);
534 0           return false;
535             }
536              
537             /* Read exponent if exists */
538 0 0         if (*str_read == 'e' || *str_read == 'E') {
    0          
539 0           int nread = 0;
540             #ifdef _MSC_VER
541             # define SSCANF sscanf_s
542             #else
543             # define SSCANF sscanf
544             #endif
545 0           int read_exponent = SSCANF (++str_read, "%d%n", &exponent, &nread);
546 0           str_read += nread;
547              
548 0 0         if (!read_exponent || nread == 0) {
    0          
549 0           BSON_DECIMAL128_SET_NAN (*dec);
550 0           return false;
551             }
552              
553             #undef SSCANF
554             }
555              
556 0 0         if (*str_read) {
557 0           BSON_DECIMAL128_SET_NAN (*dec);
558 0           return false;
559             }
560              
561             /* Done reading input. */
562             /* Find first non-zero digit in digits */
563 0           first_digit = 0;
564              
565 0 0         if (!ndigits_stored) { /* value is zero */
566 0           first_digit = 0;
567 0           last_digit = 0;
568 0           digits[0] = 0;
569 0           ndigits = 1;
570 0           ndigits_stored = 1;
571 0           significant_digits = 0;
572             } else {
573 0           last_digit = ndigits_stored - 1;
574 0           significant_digits = ndigits;
575             /* Mark trailing zeros as non-significant */
576 0 0         while (string[first_nonzero + significant_digits - 1 +
577 0           includes_sign + saw_radix] == '0') {
578 0           significant_digits--;
579             }
580             }
581              
582              
583             /* Normalization of exponent */
584             /* Correct exponent based on radix position, and shift significand as needed */
585             /* to represent user input */
586              
587             /* Overflow prevention */
588 0 0         if (exponent <= radix_position && radix_position - exponent > (1 << 14)) {
    0          
589 0           exponent = BSON_DECIMAL128_EXPONENT_MIN;
590             } else {
591 0           exponent -= radix_position;
592             }
593              
594             /* Attempt to normalize the exponent */
595 0 0         while (exponent > BSON_DECIMAL128_EXPONENT_MAX) {
596             /* Shift exponent to significand and decrease */
597 0           last_digit++;
598              
599 0 0         if (last_digit - first_digit > BSON_DECIMAL128_MAX_DIGITS) {
600             /* The exponent is too great to shift into the significand. */
601 0 0         if (significant_digits == 0) {
602             /* Value is zero, we are allowed to clamp the exponent. */
603 0           exponent = BSON_DECIMAL128_EXPONENT_MAX;
604 0           break;
605             }
606              
607             /* Overflow is not permitted, error. */
608 0           BSON_DECIMAL128_SET_NAN (*dec);
609 0           return false;
610             }
611              
612 0           exponent--;
613             }
614              
615 0 0         while (exponent < BSON_DECIMAL128_EXPONENT_MIN ||
    0          
616 0           ndigits_stored < ndigits) {
617             /* Shift last digit */
618 0 0         if (last_digit == 0) {
619             /* underflow is not allowed, but zero clamping is */
620 0 0         if (significant_digits == 0) {
621 0           exponent = BSON_DECIMAL128_EXPONENT_MIN;
622 0           break;
623             }
624              
625 0           BSON_DECIMAL128_SET_NAN (*dec);
626 0           return false;
627             }
628              
629 0 0         if (ndigits_stored < ndigits) {
630 0 0         if (string[ndigits - 1 + includes_sign + saw_radix] - '0' != 0 &&
    0          
631             significant_digits != 0) {
632 0           BSON_DECIMAL128_SET_NAN (*dec);
633 0           return false;
634             }
635              
636 0           ndigits--; /* adjust to match digits not stored */
637             } else {
638 0 0         if (digits[last_digit] != 0) {
639             /* Inexact rounding is not allowed. */
640 0           BSON_DECIMAL128_SET_NAN (*dec);
641 0           return false;
642             }
643              
644              
645 0           last_digit--; /* adjust to round */
646             }
647              
648 0 0         if (exponent < BSON_DECIMAL128_EXPONENT_MAX) {
649 0           exponent++;
650             } else {
651 0           BSON_DECIMAL128_SET_NAN (*dec);
652 0           return false;
653             }
654             }
655              
656             /* Round */
657             /* We've normalized the exponent, but might still need to round. */
658 0 0         if (last_digit - first_digit + 1 < significant_digits) {
659 0           size_t end_of_string = ndigits_read + includes_sign + saw_radix;
660             uint8_t round_digit;
661 0           uint8_t round_bit = 0;
662              
663             /* There are non-zero digits after last_digit that need rounding. */
664             /* We round to nearest, ties to even */
665 0           round_digit =
666 0           string[first_nonzero + last_digit + includes_sign + saw_radix + 1] -
667             '0';
668              
669 0 0         if (round_digit != 0) {
670             /* Inexact (non-zero) rounding is not allowed */
671 0           BSON_DECIMAL128_SET_NAN (*dec);
672 0           return false;
673             }
674             }
675              
676             /* Encode significand */
677 0           significand_high = 0, /* The high 17 digits of the significand */
678 0           significand_low = 0; /* The low 17 digits of the significand */
679              
680 0 0         if (significant_digits == 0) { /* read a zero */
681 0           significand_high = 0;
682 0           significand_low = 0;
683 0 0         } else if (last_digit - first_digit < 17) {
684 0           int d_idx = first_digit;
685 0           significand_low = digits[d_idx++];
686              
687 0 0         for (; d_idx <= last_digit; d_idx++) {
688 0           significand_low *= 10;
689 0           significand_low += digits[d_idx];
690 0           significand_high = 0;
691             }
692             } else {
693 0           int d_idx = first_digit;
694 0           significand_high = digits[d_idx++];
695              
696 0 0         for (; d_idx <= last_digit - 17; d_idx++) {
697 0           significand_high *= 10;
698 0           significand_high += digits[d_idx];
699             }
700              
701 0           significand_low = digits[d_idx++];
702              
703 0 0         for (; d_idx <= last_digit; d_idx++) {
704 0           significand_low *= 10;
705 0           significand_low += digits[d_idx];
706             }
707             }
708              
709 0           _mul_64x64 (significand_high,
710             100000000000000000ull,
711             &significand);
712 0           significand.low += significand_low;
713              
714 0 0         if (significand.low < significand_low) {
715 0           significand.high += 1;
716             }
717              
718              
719 0           biased_exponent = (exponent + (int16_t)BSON_DECIMAL128_EXPONENT_BIAS);
720              
721             /* Encode combination, exponent, and significand. */
722 0 0         if ((significand.high >> 49) & 1) {
723             /* Encode '11' into bits 1 to 3 */
724 0           dec->high |= (0x3ull << 61);
725 0           dec->high |= (biased_exponent & 0x3fffull) << 47;
726 0           dec->high |= significand.high & 0x7fffffffffffull;
727             } else {
728 0           dec->high |= (biased_exponent & 0x3fffull) << 49;
729 0           dec->high |= significand.high & 0x1ffffffffffffull;
730             }
731              
732 0           dec->low = significand.low;
733              
734             /* Encode sign */
735 0 0         if (is_negative) {
736 0           dec->high |= 0x8000000000000000ull;
737             }
738              
739 0           return true;
740             }