Code Duplication    Length = 371-374 lines in 2 locations

formio/node_modules/bson/lib/bson/decimal128.js 1 location

@@ 130-503 (lines=374) @@
127
  this.bytes = bytes;
128
}
129
130
Decimal128.fromString = function(string) {
131
  // Parse state tracking
132
  var isNegative = false;
133
  var sawRadix = false;
134
  var foundNonZero = false;
135
136
  // Total number of significant digits (no leading or trailing zero)
137
  var significantDigits = 0;
138
  // Total number of significand digits read
139
  var nDigitsRead = 0;
140
  // Total number of digits (no leading zeros)
141
  var nDigits = 0;
142
  // The number of the digits after radix
143
  var radixPosition = 0;
144
  // The index of the first non-zero in *str*
145
  var firstNonZero = 0;
146
147
  // Digits Array
148
  var digits = [0];
149
  // The number of digits in digits
150
  var nDigitsStored = 0;
151
  // Insertion pointer for digits
152
  var digitsInsert = 0;
153
  // The index of the first non-zero digit
154
  var firstDigit = 0;
155
  // The index of the last digit
156
  var lastDigit = 0;
157
158
  // Exponent
159
  var exponent = 0;
160
  // loop index over array
161
  var i = 0;
162
  // The high 17 digits of the significand
163
  var significandHigh = [0, 0];
164
  // The low 17 digits of the significand
165
  var significandLow = [0, 0];
166
  // The biased exponent
167
  var biasedExponent = 0;
168
169
  // Read index
170
  var index = 0;
171
172
  // Trim the string
173
  string = string.trim();
174
175
  // Results
176
  var stringMatch = string.match(PARSE_STRING_REGEXP);
177
  var infMatch = string.match(PARSE_INF_REGEXP);
178
  var nanMatch = string.match(PARSE_NAN_REGEXP);
179
180
  // Validate the string
181
  if(!stringMatch
182
    && ! infMatch
183
    && ! nanMatch || string.length == 0) {
184
      throw new Error("" + string + " not a valid Decimal128 string");
185
  }
186
187
  // Check if we have an illegal exponent format
188
  if(stringMatch && stringMatch[4] && stringMatch[2] === undefined) {
189
    throw new Error("" + string + " not a valid Decimal128 string");
190
  }
191
192
  // Get the negative or positive sign
193
  if(string[index] == '+' || string[index] == '-') {
194
    isNegative = string[index++] == '-';
195
  }
196
197
  // Check if user passed Infinity or NaN
198
  if(!isDigit(string[index]) && string[index] != '.') {
199
    if(string[index] == 'i' || string[index] == 'I') {
200
      return new Decimal128(new Buffer(isNegative ? INF_NEGATIVE_BUFFER : INF_POSITIVE_BUFFER));
201
    } else if(string[index] == 'N') {
202
      return new Decimal128(new Buffer(NAN_BUFFER));
203
    }
204
  }
205
206
  // Read all the digits
207
  while(isDigit(string[index]) || string[index] == '.') {
208
    if(string[index] == '.') {
209
      if(sawRadix) {
210
        return new Decimal128(new Buffer(NAN_BUFFER));
211
      }
212
213
      sawRadix = true;
214
      index = index + 1;
215
      continue;
216
    }
217
218
    if(nDigitsStored < 34) {
219
      if(string[index] != '0' || foundNonZero) {
220
        if(!foundNonZero) {
221
          firstNonZero = nDigitsRead;
222
        }
223
224
        foundNonZero = true;
225
226
        // Only store 34 digits
227
        digits[digitsInsert++] = parseInt(string[index], 10);
228
        nDigitsStored = nDigitsStored + 1;
229
      }
230
    }
231
232
    if(foundNonZero) {
233
      nDigits = nDigits + 1;
234
    }
235
236
    if(sawRadix) {
237
      radixPosition = radixPosition + 1;
238
    }
239
240
    nDigitsRead = nDigitsRead + 1;
241
    index = index + 1;
242
  }
243
244
  if(sawRadix && !nDigitsRead) {
245
    throw new Error("" + string + " not a valid Decimal128 string");
246
  }
247
248
  // Read exponent if exists
249
  if(string[index] == 'e' || string[index] == 'E') {
250
    // Read exponent digits
251
    var match = string.substr(++index).match(EXPONENT_REGEX);
252
253
    // No digits read
254
    if(!match || !match[2]) {
255
      return new Decimal128(new Buffer(NAN_BUFFER));
256
    }
257
258
    // Get exponent
259
    exponent = parseInt(match[0], 10);
260
261
    // Adjust the index
262
    index = index + match[0].length;
263
  }
264
265
  // Return not a number
266
  if(string[index]) {
267
    return new Decimal128(new Buffer(NAN_BUFFER));
268
  }
269
270
  // Done reading input
271
  // Find first non-zero digit in digits
272
  firstDigit = 0;
273
274
  if(!nDigitsStored) {
275
    firstDigit = 0;
276
    lastDigit = 0;
277
    digits[0] = 0;
278
    nDigits = 1;
279
    nDigitsStored = 1;
280
    significantDigits = 0;
281
  } else {
282
    lastDigit = nDigitsStored - 1;
283
    significantDigits = nDigits;
284
285
    if(exponent != 0 && significantDigits != 1) {
286
      while(string[firstNonZero + significantDigits - 1] == '0') {
287
        significantDigits = significantDigits - 1;
288
      }
289
    }
290
  }
291
292
  // Normalization of exponent
293
  // Correct exponent based on radix position, and shift significand as needed
294
  // to represent user input
295
296
  // Overflow prevention
297
  if(exponent <= radixPosition && radixPosition - exponent > (1 << 14)) {
298
    exponent = EXPONENT_MIN;
299
  } else {
300
    exponent = exponent - radixPosition;
301
  }
302
303
  // Attempt to normalize the exponent
304
  while(exponent > EXPONENT_MAX) {
305
    // Shift exponent to significand and decrease
306
    lastDigit = lastDigit + 1;
307
308
    if(lastDigit - firstDigit > MAX_DIGITS) {
309
      // Check if we have a zero then just hard clamp, otherwise fail
310
      var digitsString = digits.join('');
311
      if(digitsString.match(/^0+$/)) {
312
        exponent = EXPONENT_MAX;
313
        break;
314
      } else {
315
        return new Decimal128(new Buffer(isNegative ? INF_NEGATIVE_BUFFER : INF_POSITIVE_BUFFER));
316
      }
317
    }
318
319
    exponent = exponent - 1;
320
  }
321
322
  while(exponent < EXPONENT_MIN || nDigitsStored < nDigits) {
323
    // Shift last digit
324
    if(lastDigit == 0) {
325
      exponent = EXPONENT_MIN;
326
      significantDigits = 0;
327
      break;
328
    }
329
330
    if(nDigitsStored < nDigits) {
331
      // adjust to match digits not stored
332
      nDigits = nDigits - 1;
333
    } else {
334
      // adjust to round
335
      lastDigit = lastDigit - 1;
336
    }
337
338
    if(exponent < EXPONENT_MAX) {
339
      exponent = exponent + 1;
340
    } else {
341
      // Check if we have a zero then just hard clamp, otherwise fail
342
      var digitsString = digits.join('');
343
      if(digitsString.match(/^0+$/)) {
344
        exponent = EXPONENT_MAX;
345
        break;
346
      } else {
347
        return new Decimal128(new Buffer(isNegative ? INF_NEGATIVE_BUFFER : INF_POSITIVE_BUFFER))
348
      }
349
    }
350
  }
351
352
353
  // Round
354
  // We've normalized the exponent, but might still need to round.
355
  if((lastDigit - firstDigit + 1 < significantDigits) && string[significantDigits] != '0') {
356
    var endOfString = nDigitsRead;
357
358
    // If we have seen a radix point, 'string' is 1 longer than we have
359
    // documented with ndigits_read, so inc the position of the first nonzero
360
    // digit and the position that digits are read to.
361
    if(sawRadix && exponent == EXPONENT_MIN) {
362
      firstNonZero = firstNonZero + 1;
363
      endOfString = endOfString + 1;
364
    }
365
366
    var roundDigit = parseInt(string[firstNonZero + lastDigit + 1], 10);
367
    var roundBit = 0;
368
369
    if(roundDigit >= 5) {
370
      roundBit = 1;
371
372
      if(roundDigit == 5) {
373
        roundBit = digits[lastDigit] % 2 == 1;
374
375
        for(var i = firstNonZero + lastDigit + 2; i < endOfString; i++) {
376
          if(parseInt(string[i], 10)) {
377
            roundBit = 1;
378
            break;
379
          }
380
        }
381
      }
382
    }
383
384
    if(roundBit) {
385
      var dIdx = lastDigit;
386
387
      for(; dIdx >= 0; dIdx--) {
388
        if(++digits[dIdx] > 9) {
389
          digits[dIdx] = 0;
390
391
          // overflowed most significant digit
392
          if(dIdx == 0) {
393
            if(exponent < EXPONENT_MAX) {
394
              exponent = exponent + 1;
395
              digits[dIdx] = 1;
396
            } else {
397
              return new Decimal128(new Buffer(isNegative ? INF_NEGATIVE_BUFFER : INF_POSITIVE_BUFFER))
398
            }
399
          }
400
        } else {
401
          break;
402
        }
403
      }
404
    }
405
  }
406
407
  // Encode significand
408
  // The high 17 digits of the significand
409
  significandHigh = Long.fromNumber(0);
410
  // The low 17 digits of the significand
411
  significandLow = Long.fromNumber(0);
412
413
  // read a zero
414
  if(significantDigits == 0) {
415
    significandHigh = Long.fromNumber(0);
416
    significandLow = Long.fromNumber(0);
417
  } else if(lastDigit - firstDigit < 17) {
418
    var dIdx = firstDigit;
419
    significandLow = Long.fromNumber(digits[dIdx++]);
420
    significandHigh = new Long(0, 0);
421
422
    for(; dIdx <= lastDigit; dIdx++) {
423
      significandLow = significandLow.multiply(Long.fromNumber(10));
424
      significandLow = significandLow.add(Long.fromNumber(digits[dIdx]));
425
    }
426
  } else {
427
    var dIdx = firstDigit;
428
    significandHigh = Long.fromNumber(digits[dIdx++]);
429
430
    for(; dIdx <= lastDigit - 17; dIdx++) {
431
      significandHigh = significandHigh.multiply(Long.fromNumber(10));
432
      significandHigh = significandHigh.add(Long.fromNumber(digits[dIdx]));
433
    }
434
435
    significandLow = Long.fromNumber(digits[dIdx++]);
436
437
    for(; dIdx <= lastDigit; dIdx++) {
438
      significandLow = significandLow.multiply(Long.fromNumber(10));
439
      significandLow = significandLow.add(Long.fromNumber(digits[dIdx]));
440
    }
441
  }
442
443
  var significand = multiply64x2(significandHigh, Long.fromString("100000000000000000"));
444
445
  significand.low = significand.low.add(significandLow);
446
447
  if(lessThan(significand.low, significandLow)) {
448
    significand.high = significand.high.add(Long.fromNumber(1));
449
  }
450
451
  // Biased exponent
452
  var biasedExponent = (exponent + EXPONENT_BIAS);
453
  var dec = { low: Long.fromNumber(0), high: Long.fromNumber(0) };
454
455
  // Encode combination, exponent, and significand.
456
  if(significand.high.shiftRightUnsigned(49).and(Long.fromNumber(1)).equals(Long.fromNumber)) {
457
    // Encode '11' into bits 1 to 3
458
    dec.high = dec.high.or(Long.fromNumber(0x3).shiftLeft(61));
459
    dec.high = dec.high.or(Long.fromNumber(biasedExponent).and(Long.fromNumber(0x3fff).shiftLeft(47)));
460
    dec.high = dec.high.or(significand.high.and(Long.fromNumber(0x7fffffffffff)));
461
  } else {
462
    dec.high = dec.high.or(Long.fromNumber(biasedExponent & 0x3fff).shiftLeft(49));
463
    dec.high = dec.high.or(significand.high.and(Long.fromNumber(0x1ffffffffffff)));
464
  }
465
466
  dec.low = significand.low;
467
468
  // Encode sign
469
  if(isNegative) {
470
    dec.high = dec.high.or(Long.fromString('9223372036854775808'));
471
  }
472
473
  // Encode into a buffer
474
  var buffer = new Buffer(16);
475
  var index = 0;
476
477
  // Encode the low 64 bits of the decimal
478
  // Encode low bits
479
  buffer[index++] = dec.low.low_ & 0xff;
480
  buffer[index++] = (dec.low.low_ >> 8) & 0xff;
481
  buffer[index++] = (dec.low.low_ >> 16) & 0xff;
482
  buffer[index++] = (dec.low.low_ >> 24) & 0xff;
483
  // Encode high bits
484
  buffer[index++] = dec.low.high_ & 0xff;
485
  buffer[index++] = (dec.low.high_ >> 8) & 0xff;
486
  buffer[index++] = (dec.low.high_ >> 16) & 0xff;
487
  buffer[index++] = (dec.low.high_ >> 24) & 0xff;
488
489
  // Encode the high 64 bits of the decimal
490
  // Encode low bits
491
  buffer[index++] = dec.high.low_ & 0xff;
492
  buffer[index++] = (dec.high.low_ >> 8) & 0xff;
493
  buffer[index++] = (dec.high.low_ >> 16) & 0xff;
494
  buffer[index++] = (dec.high.low_ >> 24) & 0xff;
495
  // Encode high bits
496
  buffer[index++] = dec.high.high_ & 0xff;
497
  buffer[index++] = (dec.high.high_ >> 8) & 0xff;
498
  buffer[index++] = (dec.high.high_ >> 16) & 0xff;
499
  buffer[index++] = (dec.high.high_ >> 24) & 0xff;
500
501
  // Return the new Decimal128
502
  return new Decimal128(buffer);
503
}
504
505
// Extract least significant 5 bits
506
var COMBINATION_MASK = 0x1f;

formio/node_modules/bson/browser_build/bson.js 1 location

@@ 13243-13613 (lines=371) @@
13240
	  this.bytes = bytes;
13241
	};
13242
13243
	Decimal128.fromString = function (string) {
13244
	  // Parse state tracking
13245
	  var isNegative = false;
13246
	  var sawRadix = false;
13247
	  var foundNonZero = false;
13248
13249
	  // Total number of significant digits (no leading or trailing zero)
13250
	  var significantDigits = 0;
13251
	  // Total number of significand digits read
13252
	  var nDigitsRead = 0;
13253
	  // Total number of digits (no leading zeros)
13254
	  var nDigits = 0;
13255
	  // The number of the digits after radix
13256
	  var radixPosition = 0;
13257
	  // The index of the first non-zero in *str*
13258
	  var firstNonZero = 0;
13259
13260
	  // Digits Array
13261
	  var digits = [0];
13262
	  // The number of digits in digits
13263
	  var nDigitsStored = 0;
13264
	  // Insertion pointer for digits
13265
	  var digitsInsert = 0;
13266
	  // The index of the first non-zero digit
13267
	  var firstDigit = 0;
13268
	  // The index of the last digit
13269
	  var lastDigit = 0;
13270
13271
	  // Exponent
13272
	  var exponent = 0;
13273
	  // loop index over array
13274
	  var i = 0;
13275
	  // The high 17 digits of the significand
13276
	  var significandHigh = [0, 0];
13277
	  // The low 17 digits of the significand
13278
	  var significandLow = [0, 0];
13279
	  // The biased exponent
13280
	  var biasedExponent = 0;
13281
13282
	  // Read index
13283
	  var index = 0;
13284
13285
	  // Trim the string
13286
	  string = string.trim();
13287
13288
	  // Results
13289
	  var stringMatch = string.match(PARSE_STRING_REGEXP);
13290
	  var infMatch = string.match(PARSE_INF_REGEXP);
13291
	  var nanMatch = string.match(PARSE_NAN_REGEXP);
13292
13293
	  // Validate the string
13294
	  if (!stringMatch && !infMatch && !nanMatch || string.length == 0) {
13295
	    throw new Error("" + string + " not a valid Decimal128 string");
13296
	  }
13297
13298
	  // Check if we have an illegal exponent format
13299
	  if (stringMatch && stringMatch[4] && stringMatch[2] === undefined) {
13300
	    throw new Error("" + string + " not a valid Decimal128 string");
13301
	  }
13302
13303
	  // Get the negative or positive sign
13304
	  if (string[index] == '+' || string[index] == '-') {
13305
	    isNegative = string[index++] == '-';
13306
	  }
13307
13308
	  // Check if user passed Infinity or NaN
13309
	  if (!isDigit(string[index]) && string[index] != '.') {
13310
	    if (string[index] == 'i' || string[index] == 'I') {
13311
	      return new Decimal128(new Buffer(isNegative ? INF_NEGATIVE_BUFFER : INF_POSITIVE_BUFFER));
13312
	    } else if (string[index] == 'N') {
13313
	      return new Decimal128(new Buffer(NAN_BUFFER));
13314
	    }
13315
	  }
13316
13317
	  // Read all the digits
13318
	  while (isDigit(string[index]) || string[index] == '.') {
13319
	    if (string[index] == '.') {
13320
	      if (sawRadix) {
13321
	        return new Decimal128(new Buffer(NAN_BUFFER));
13322
	      }
13323
13324
	      sawRadix = true;
13325
	      index = index + 1;
13326
	      continue;
13327
	    }
13328
13329
	    if (nDigitsStored < 34) {
13330
	      if (string[index] != '0' || foundNonZero) {
13331
	        if (!foundNonZero) {
13332
	          firstNonZero = nDigitsRead;
13333
	        }
13334
13335
	        foundNonZero = true;
13336
13337
	        // Only store 34 digits
13338
	        digits[digitsInsert++] = parseInt(string[index], 10);
13339
	        nDigitsStored = nDigitsStored + 1;
13340
	      }
13341
	    }
13342
13343
	    if (foundNonZero) {
13344
	      nDigits = nDigits + 1;
13345
	    }
13346
13347
	    if (sawRadix) {
13348
	      radixPosition = radixPosition + 1;
13349
	    }
13350
13351
	    nDigitsRead = nDigitsRead + 1;
13352
	    index = index + 1;
13353
	  }
13354
13355
	  if (sawRadix && !nDigitsRead) {
13356
	    throw new Error("" + string + " not a valid Decimal128 string");
13357
	  }
13358
13359
	  // Read exponent if exists
13360
	  if (string[index] == 'e' || string[index] == 'E') {
13361
	    // Read exponent digits
13362
	    var match = string.substr(++index).match(EXPONENT_REGEX);
13363
13364
	    // No digits read
13365
	    if (!match || !match[2]) {
13366
	      return new Decimal128(new Buffer(NAN_BUFFER));
13367
	    }
13368
13369
	    // Get exponent
13370
	    exponent = parseInt(match[0], 10);
13371
13372
	    // Adjust the index
13373
	    index = index + match[0].length;
13374
	  }
13375
13376
	  // Return not a number
13377
	  if (string[index]) {
13378
	    return new Decimal128(new Buffer(NAN_BUFFER));
13379
	  }
13380
13381
	  // Done reading input
13382
	  // Find first non-zero digit in digits
13383
	  firstDigit = 0;
13384
13385
	  if (!nDigitsStored) {
13386
	    firstDigit = 0;
13387
	    lastDigit = 0;
13388
	    digits[0] = 0;
13389
	    nDigits = 1;
13390
	    nDigitsStored = 1;
13391
	    significantDigits = 0;
13392
	  } else {
13393
	    lastDigit = nDigitsStored - 1;
13394
	    significantDigits = nDigits;
13395
13396
	    if (exponent != 0 && significantDigits != 1) {
13397
	      while (string[firstNonZero + significantDigits - 1] == '0') {
13398
	        significantDigits = significantDigits - 1;
13399
	      }
13400
	    }
13401
	  }
13402
13403
	  // Normalization of exponent
13404
	  // Correct exponent based on radix position, and shift significand as needed
13405
	  // to represent user input
13406
13407
	  // Overflow prevention
13408
	  if (exponent <= radixPosition && radixPosition - exponent > 1 << 14) {
13409
	    exponent = EXPONENT_MIN;
13410
	  } else {
13411
	    exponent = exponent - radixPosition;
13412
	  }
13413
13414
	  // Attempt to normalize the exponent
13415
	  while (exponent > EXPONENT_MAX) {
13416
	    // Shift exponent to significand and decrease
13417
	    lastDigit = lastDigit + 1;
13418
13419
	    if (lastDigit - firstDigit > MAX_DIGITS) {
13420
	      // Check if we have a zero then just hard clamp, otherwise fail
13421
	      var digitsString = digits.join('');
13422
	      if (digitsString.match(/^0+$/)) {
13423
	        exponent = EXPONENT_MAX;
13424
	        break;
13425
	      } else {
13426
	        return new Decimal128(new Buffer(isNegative ? INF_NEGATIVE_BUFFER : INF_POSITIVE_BUFFER));
13427
	      }
13428
	    }
13429
13430
	    exponent = exponent - 1;
13431
	  }
13432
13433
	  while (exponent < EXPONENT_MIN || nDigitsStored < nDigits) {
13434
	    // Shift last digit
13435
	    if (lastDigit == 0) {
13436
	      exponent = EXPONENT_MIN;
13437
	      significantDigits = 0;
13438
	      break;
13439
	    }
13440
13441
	    if (nDigitsStored < nDigits) {
13442
	      // adjust to match digits not stored
13443
	      nDigits = nDigits - 1;
13444
	    } else {
13445
	      // adjust to round
13446
	      lastDigit = lastDigit - 1;
13447
	    }
13448
13449
	    if (exponent < EXPONENT_MAX) {
13450
	      exponent = exponent + 1;
13451
	    } else {
13452
	      // Check if we have a zero then just hard clamp, otherwise fail
13453
	      var digitsString = digits.join('');
13454
	      if (digitsString.match(/^0+$/)) {
13455
	        exponent = EXPONENT_MAX;
13456
	        break;
13457
	      } else {
13458
	        return new Decimal128(new Buffer(isNegative ? INF_NEGATIVE_BUFFER : INF_POSITIVE_BUFFER));
13459
	      }
13460
	    }
13461
	  }
13462
13463
	  // Round
13464
	  // We've normalized the exponent, but might still need to round.
13465
	  if (lastDigit - firstDigit + 1 < significantDigits && string[significantDigits] != '0') {
13466
	    var endOfString = nDigitsRead;
13467
13468
	    // If we have seen a radix point, 'string' is 1 longer than we have
13469
	    // documented with ndigits_read, so inc the position of the first nonzero
13470
	    // digit and the position that digits are read to.
13471
	    if (sawRadix && exponent == EXPONENT_MIN) {
13472
	      firstNonZero = firstNonZero + 1;
13473
	      endOfString = endOfString + 1;
13474
	    }
13475
13476
	    var roundDigit = parseInt(string[firstNonZero + lastDigit + 1], 10);
13477
	    var roundBit = 0;
13478
13479
	    if (roundDigit >= 5) {
13480
	      roundBit = 1;
13481
13482
	      if (roundDigit == 5) {
13483
	        roundBit = digits[lastDigit] % 2 == 1;
13484
13485
	        for (var i = firstNonZero + lastDigit + 2; i < endOfString; i++) {
13486
	          if (parseInt(string[i], 10)) {
13487
	            roundBit = 1;
13488
	            break;
13489
	          }
13490
	        }
13491
	      }
13492
	    }
13493
13494
	    if (roundBit) {
13495
	      var dIdx = lastDigit;
13496
13497
	      for (; dIdx >= 0; dIdx--) {
13498
	        if (++digits[dIdx] > 9) {
13499
	          digits[dIdx] = 0;
13500
13501
	          // overflowed most significant digit
13502
	          if (dIdx == 0) {
13503
	            if (exponent < EXPONENT_MAX) {
13504
	              exponent = exponent + 1;
13505
	              digits[dIdx] = 1;
13506
	            } else {
13507
	              return new Decimal128(new Buffer(isNegative ? INF_NEGATIVE_BUFFER : INF_POSITIVE_BUFFER));
13508
	            }
13509
	          }
13510
	        } else {
13511
	          break;
13512
	        }
13513
	      }
13514
	    }
13515
	  }
13516
13517
	  // Encode significand
13518
	  // The high 17 digits of the significand
13519
	  significandHigh = Long.fromNumber(0);
13520
	  // The low 17 digits of the significand
13521
	  significandLow = Long.fromNumber(0);
13522
13523
	  // read a zero
13524
	  if (significantDigits == 0) {
13525
	    significandHigh = Long.fromNumber(0);
13526
	    significandLow = Long.fromNumber(0);
13527
	  } else if (lastDigit - firstDigit < 17) {
13528
	    var dIdx = firstDigit;
13529
	    significandLow = Long.fromNumber(digits[dIdx++]);
13530
	    significandHigh = new Long(0, 0);
13531
13532
	    for (; dIdx <= lastDigit; dIdx++) {
13533
	      significandLow = significandLow.multiply(Long.fromNumber(10));
13534
	      significandLow = significandLow.add(Long.fromNumber(digits[dIdx]));
13535
	    }
13536
	  } else {
13537
	    var dIdx = firstDigit;
13538
	    significandHigh = Long.fromNumber(digits[dIdx++]);
13539
13540
	    for (; dIdx <= lastDigit - 17; dIdx++) {
13541
	      significandHigh = significandHigh.multiply(Long.fromNumber(10));
13542
	      significandHigh = significandHigh.add(Long.fromNumber(digits[dIdx]));
13543
	    }
13544
13545
	    significandLow = Long.fromNumber(digits[dIdx++]);
13546
13547
	    for (; dIdx <= lastDigit; dIdx++) {
13548
	      significandLow = significandLow.multiply(Long.fromNumber(10));
13549
	      significandLow = significandLow.add(Long.fromNumber(digits[dIdx]));
13550
	    }
13551
	  }
13552
13553
	  var significand = multiply64x2(significandHigh, Long.fromString("100000000000000000"));
13554
13555
	  significand.low = significand.low.add(significandLow);
13556
13557
	  if (lessThan(significand.low, significandLow)) {
13558
	    significand.high = significand.high.add(Long.fromNumber(1));
13559
	  }
13560
13561
	  // Biased exponent
13562
	  var biasedExponent = exponent + EXPONENT_BIAS;
13563
	  var dec = { low: Long.fromNumber(0), high: Long.fromNumber(0) };
13564
13565
	  // Encode combination, exponent, and significand.
13566
	  if (significand.high.shiftRightUnsigned(49).and(Long.fromNumber(1)).equals(Long.fromNumber)) {
13567
	    // Encode '11' into bits 1 to 3
13568
	    dec.high = dec.high.or(Long.fromNumber(0x3).shiftLeft(61));
13569
	    dec.high = dec.high.or(Long.fromNumber(biasedExponent).and(Long.fromNumber(0x3fff).shiftLeft(47)));
13570
	    dec.high = dec.high.or(significand.high.and(Long.fromNumber(0x7fffffffffff)));
13571
	  } else {
13572
	    dec.high = dec.high.or(Long.fromNumber(biasedExponent & 0x3fff).shiftLeft(49));
13573
	    dec.high = dec.high.or(significand.high.and(Long.fromNumber(0x1ffffffffffff)));
13574
	  }
13575
13576
	  dec.low = significand.low;
13577
13578
	  // Encode sign
13579
	  if (isNegative) {
13580
	    dec.high = dec.high.or(Long.fromString('9223372036854775808'));
13581
	  }
13582
13583
	  // Encode into a buffer
13584
	  var buffer = new Buffer(16);
13585
	  var index = 0;
13586
13587
	  // Encode the low 64 bits of the decimal
13588
	  // Encode low bits
13589
	  buffer[index++] = dec.low.low_ & 0xff;
13590
	  buffer[index++] = dec.low.low_ >> 8 & 0xff;
13591
	  buffer[index++] = dec.low.low_ >> 16 & 0xff;
13592
	  buffer[index++] = dec.low.low_ >> 24 & 0xff;
13593
	  // Encode high bits
13594
	  buffer[index++] = dec.low.high_ & 0xff;
13595
	  buffer[index++] = dec.low.high_ >> 8 & 0xff;
13596
	  buffer[index++] = dec.low.high_ >> 16 & 0xff;
13597
	  buffer[index++] = dec.low.high_ >> 24 & 0xff;
13598
13599
	  // Encode the high 64 bits of the decimal
13600
	  // Encode low bits
13601
	  buffer[index++] = dec.high.low_ & 0xff;
13602
	  buffer[index++] = dec.high.low_ >> 8 & 0xff;
13603
	  buffer[index++] = dec.high.low_ >> 16 & 0xff;
13604
	  buffer[index++] = dec.high.low_ >> 24 & 0xff;
13605
	  // Encode high bits
13606
	  buffer[index++] = dec.high.high_ & 0xff;
13607
	  buffer[index++] = dec.high.high_ >> 8 & 0xff;
13608
	  buffer[index++] = dec.high.high_ >> 16 & 0xff;
13609
	  buffer[index++] = dec.high.high_ >> 24 & 0xff;
13610
13611
	  // Return the new Decimal128
13612
	  return new Decimal128(buffer);
13613
	};
13614
13615
	// Extract least significant 5 bits
13616
	var COMBINATION_MASK = 0x1f;