obj_long.c
Go to the documentation of this file.
1 
20 #include <kuroko/vm.h>
21 #include <kuroko/value.h>
22 #include <kuroko/util.h>
23 #include "private.h"
24 
25 #define DIGIT_SHIFT 31
26 #define DIGIT_MAX 0x7FFFFFFF
27 
29  ssize_t width;
30  uint32_t *digits;
31 };
32 
33 typedef struct KrkLong_Internal KrkLong;
34 
40 static int krk_long_init_si(KrkLong * num, int64_t val) {
41 
42  /* Special-case for 0: width = 0, no digits. */
43  if (val == 0) {
44  num->width = 0;
45  num->digits = NULL;
46  return 0;
47  }
48 
49  /* Digits store unsigned values, so flip things over. */
50  int sign = (val < 0) ? -1 : 1;
51  uint64_t abs = (val < 0) ? -val : val;
52 
53  /* Quick case for things that fit in our digits... */
54  if (abs <= DIGIT_MAX) {
55  num->width = sign;
56  num->digits = malloc(sizeof(uint32_t));
57  num->digits[0] = abs;
58  return 0;
59  }
60 
61  /* Figure out how many digits we need. */
62  uint64_t tmp = abs;
63  int64_t cnt = 1;
64 
65  while (tmp > DIGIT_MAX) {
66  cnt++;
67  tmp >>= DIGIT_SHIFT;
68  }
69 
70  /* Allocate space */
71  num->width = cnt * sign;
72  num->digits = malloc(sizeof(uint32_t) * cnt);
73 
74  /* Extract digits. */
75  for (int64_t i = 0; i < cnt; ++i) {
76  num->digits[i] = (abs & DIGIT_MAX);
77  abs >>= DIGIT_SHIFT;
78  }
79 
80  return 0;
81 }
82 
86 static int krk_long_init_ui(KrkLong * num, uint64_t val) {
87 
88  /* Special-case for 0: width = 0, no digits. */
89  if (val == 0) {
90  num->width = 0;
91  num->digits = NULL;
92  return 0;
93  }
94 
95  if (val <= DIGIT_MAX) {
96  num->width = 1;
97  num->digits = malloc(sizeof(uint32_t));
98  num->digits[0] = val;
99  return 0;
100  }
101 
102  /* Figure out how many digits we need. */
103  uint64_t tmp = val;
104  uint64_t cnt = 1;
105 
106  while (tmp > DIGIT_MAX) {
107  cnt++;
108  tmp >>= DIGIT_SHIFT;
109  }
110 
111  /* Allocate space */
112  num->width = cnt;
113  num->digits = malloc(sizeof(uint32_t) * cnt);
114 
115  /* Extract digits. */
116  for (uint64_t i = 0; i < cnt; ++i) {
117  num->digits[i] = (val & DIGIT_MAX);
118  val >>= DIGIT_SHIFT;
119  }
120 
121  return 0;
122 }
123 
129 static int krk_long_init_many(KrkLong *a, ...) {
130  va_list argp;
131  va_start(argp, a);
132 
133  KrkLong * next = a;
134  while (next) {
135  krk_long_init_si(next, 0);
136  next = va_arg(argp, KrkLong *);
137  }
138 
139  va_end(argp);
140  return 0;
141 }
142 
149 static int krk_long_init_copy(KrkLong * out, const KrkLong * in) {
150  size_t abs_width = in->width < 0 ? -in->width : in->width;
151  out->width = in->width;
152  out->digits = out->width ? malloc(sizeof(uint32_t) * abs_width) : NULL;
153  for (size_t i = 0; i < abs_width; ++i) {
154  out->digits[i] = in->digits[i];
155  }
156  return 0;
157 }
158 
159 
165 static int krk_long_clear(KrkLong * num) {
166  if (num->digits) free(num->digits);
167  num->width = 0;
168  num->digits = NULL;
169  return 0;
170 }
171 
177 static int krk_long_clear_many(KrkLong *a, ...) {
178  va_list argp;
179  va_start(argp, a);
180 
181  KrkLong * next = a;
182  while (next) {
183  krk_long_clear(next);
184  next = va_arg(argp, KrkLong *);
185  }
186 
187  va_end(argp);
188  return 0;
189 }
190 
197 static int krk_long_resize(KrkLong * num, ssize_t newdigits) {
198  if (newdigits == 0) {
199  krk_long_clear(num);
200  return 0;
201  }
202 
203  size_t abs = newdigits < 0 ? -newdigits : newdigits;
204  size_t eabs = num->width < 0 ? -num->width : num->width;
205  if (num->width == 0) {
206  num->digits = calloc(sizeof(uint32_t), newdigits);
207  } else if (eabs < abs) {
208  num->digits = realloc(num->digits, sizeof(uint32_t) * newdigits);
209  memset(&num->digits[eabs], 0, sizeof(uint32_t)*(abs-eabs));
210  }
211 
212  num->width = newdigits;
213  return 0;
214 }
215 
221 static int krk_long_set_sign(KrkLong * num, int sign) {
222  num->width = num->width < 0 ? (-num->width) * sign : num->width * sign;
223  return 0;
224 }
225 
232 static int krk_long_trim(KrkLong * num) {
233  int invert = num->width < 0;
234  size_t owidth = invert ? -num->width : num->width;
235  size_t redundant = 0;
236  for (size_t i = 0; i < owidth; i++) {
237  if (num->digits[owidth-i-1] == 0) {
238  redundant++;
239  } else {
240  break;
241  }
242  }
243 
244  if (redundant) {
245  krk_long_resize(num, owidth - redundant);
246  if (invert) krk_long_set_sign(num, -1);
247  }
248 
249  return 0;
250 }
251 
260 static int krk_long_compare(const KrkLong * a, const KrkLong * b) {
261  if (a->width > b->width) return 1;
262  if (b->width > a->width) return -1;
263  int sign = a->width < 0 ? -1 : 1;
264  size_t abs_width = a->width < 0 ? -a->width : a->width;
265  for (size_t i = 0; i < abs_width; ++i) {
266  if (a->digits[abs_width-i-1] > b->digits[abs_width-i-1]) return sign; /* left is bigger */
267  if (a->digits[abs_width-i-1] < b->digits[abs_width-i-1]) return -sign; /* right is bigger */
268  }
269  return 0; /* they are the same */
270 }
271 
278 static int krk_long_compare_abs(const KrkLong * a, const KrkLong * b) {
279  size_t a_width = a->width < 0 ? -a->width : a->width;
280  size_t b_width = b->width < 0 ? -b->width : b->width;
281  if (a_width > b_width) return 1;
282  if (b_width > a_width) return -1;
283  size_t abs_width = a_width;
284  for (size_t i = 0; i < abs_width; ++i) {
285  if (a->digits[abs_width-i-1] > b->digits[abs_width-i-1]) return 1; /* left is bigger */
286  if (a->digits[abs_width-i-1] < b->digits[abs_width-i-1]) return -1; /* right is bigger */
287  }
288  return 0; /* they are the same */
289 }
290 
297 static int krk_long_add_ignore_sign(KrkLong * res, const KrkLong * a, const KrkLong * b) {
298  size_t awidth = a->width < 0 ? -a->width : a->width;
299  size_t bwidth = b->width < 0 ? -b->width : b->width;
300  size_t owidth = awidth < bwidth ? bwidth + 1 : awidth + 1;
301  size_t carry = 0;
302  krk_long_resize(res, owidth);
303  for (size_t i = 0; i < owidth - 1; ++i) {
304  uint32_t out = (i < awidth ? a->digits[i] : 0) + (i < bwidth ? b->digits[i] : 0) + carry;
305  res->digits[i] = out & DIGIT_MAX;
306  carry = out > DIGIT_MAX;
307  }
308  if (carry) {
309  res->digits[owidth-1] = 1;
310  } else {
311  krk_long_resize(res, owidth - 1);
312  }
313  return 0;
314 }
315 
321 static int _sub_big_small(KrkLong * res, const KrkLong * a, const KrkLong * b) {
322  /* Subtract b from a, where a is bigger */
323  size_t awidth = a->width < 0 ? -a->width : a->width;
324  size_t bwidth = b->width < 0 ? -b->width : b->width;
325  size_t owidth = awidth;
326 
327  krk_long_resize(res, owidth);
328 
329  int carry = 0;
330 
331  for (size_t i = 0; i < owidth; ++i) {
332  /* We'll do long subtraction? */
333  int64_t a_digit = (int64_t)(i < awidth ? a->digits[i] : 0) - carry;
334  int64_t b_digit = i < bwidth ? b->digits[i] : 0;
335  if (a_digit < b_digit) {
336  a_digit += (int64_t)1 << DIGIT_SHIFT;
337  carry = 1;
338  } else {
339  carry = 0;
340  }
341 
342  res->digits[i] = (a_digit - b_digit) & DIGIT_MAX;
343  }
344 
345  krk_long_trim(res);
346 
347  return 0;
348 }
349 
353 static int _swap(KrkLong * a, KrkLong * b) {
354  ssize_t width = a->width;
355  uint32_t * digits = a->digits;
356  a->width = b->width;
357  a->digits = b->digits;
358  b->width = width;
359  b->digits = digits;
360  return 0;
361 }
362 
363 /* Macros for handling cases where res = a or res = b */
364 #define PREP_OUTPUT(res,a,b) KrkLong _tmp_out_ ## res, *_swap_out_ ## res = NULL; do { if (res == a || res == b) { krk_long_init_si(&_tmp_out_ ## res, 0); _swap_out_ ## res = res; res = &_tmp_out_ ## res; } } while (0)
365 #define PREP_OUTPUT1(res,a) KrkLong _tmp_out_ ## res, *_swap_out_ ## res = NULL; do { if (res == a) { krk_long_init_si(&_tmp_out_ ## res, 0); _swap_out_ ## res = res; res = &_tmp_out_ ## res; } } while (0)
366 #define FINISH_OUTPUT(res) do { if (_swap_out_ ## res) { _swap(_swap_out_ ## res, res); krk_long_clear(&_tmp_out_ ## res); } } while (0)
367 
373 static int krk_long_add(KrkLong * res, const KrkLong * a, const KrkLong * b) {
374  PREP_OUTPUT(res,a,b);
375 
376  if (a->width == 0) {
377  krk_long_clear(res);
378  krk_long_init_copy(res,b);
379  FINISH_OUTPUT(res);
380  return 0;
381  } else if (b->width == 0) {
382  krk_long_clear(res);
383  krk_long_init_copy(res,a);
384  FINISH_OUTPUT(res);
385  return 0;
386  }
387 
388  if (a->width < 0 && b->width > 0) {
389  switch (krk_long_compare_abs(a,b)) {
390  case -1:
391  _sub_big_small(res,b,a);
392  krk_long_set_sign(res,1);
393  FINISH_OUTPUT(res);
394  return 0;
395  case 1:
396  _sub_big_small(res,a,b);
397  krk_long_set_sign(res,-1);
398  FINISH_OUTPUT(res);
399  return 0;
400  }
401  krk_long_clear(res);
402  FINISH_OUTPUT(res);
403  return 0;
404  } else if (a->width > 0 && b->width < 0) {
405  switch (krk_long_compare_abs(a,b)) {
406  case -1:
407  _sub_big_small(res,b,a);
408  krk_long_set_sign(res,-1);
409  FINISH_OUTPUT(res);
410  return 0;
411  case 1:
412  _sub_big_small(res,a,b);
413  krk_long_set_sign(res,1);
414  FINISH_OUTPUT(res);
415  return 0;
416  }
417  krk_long_clear(res);
418  FINISH_OUTPUT(res);
419  return 0;
420  }
421 
422  /* sign must match for this, so take it from whichever */
423  int sign = a->width < 0 ? -1 : 1;
424  if (krk_long_add_ignore_sign(res,a,b)) {
425  FINISH_OUTPUT(res);
426  return 1;
427  }
428  krk_long_set_sign(res,sign);
429  FINISH_OUTPUT(res);
430  return 0;
431 }
432 
438 static int krk_long_sub(KrkLong * res, const KrkLong * a, const KrkLong * b) {
439  PREP_OUTPUT(res,a,b);
440  if (a->width == 0) {
441  krk_long_clear(res);
442  krk_long_init_copy(res,b);
443  krk_long_set_sign(res, b->width < 0 ? 1 : -1);
444  FINISH_OUTPUT(res);
445  return 0;
446  } else if (b->width == 0) {
447  krk_long_clear(res);
448  krk_long_init_copy(res,a);
449  FINISH_OUTPUT(res);
450  return 0;
451  }
452 
453  if ((a->width < 0) != (b->width < 0)) {
454  if (krk_long_add_ignore_sign(res,a,b)) { FINISH_OUTPUT(res); return 1; }
455  krk_long_set_sign(res,a->width < 0 ? -1 : 1);
456  FINISH_OUTPUT(res);
457  return 0;
458  }
459 
460  /* Which is bigger? */
461  switch (krk_long_compare_abs(a,b)) {
462  case 0:
463  krk_long_clear(res);
464  FINISH_OUTPUT(res);
465  return 0;
466  case 1:
467  _sub_big_small(res,a,b);
468  if (a->width < 0) krk_long_set_sign(res, -1);
469  FINISH_OUTPUT(res);
470  return 0;
471  case -1:
472  _sub_big_small(res,b,a);
473  if (b->width > 0) krk_long_set_sign(res, -1);
474  FINISH_OUTPUT(res);
475  return 0;
476  }
477 
478  __builtin_unreachable();
479 }
480 
486 static int krk_long_zero(KrkLong * num) {
487  size_t abs_width = num->width < 0 ? -num->width : num->width;
488  for (size_t i = 0; i < abs_width; ++i) {
489  num->digits[i] = 0;
490  }
491  return 0;
492 }
493 
503 static int _mul_abs(KrkLong * res, const KrkLong * a, const KrkLong * b) {
504 
505  size_t awidth = a->width < 0 ? -a->width : a->width;
506  size_t bwidth = b->width < 0 ? -b->width : b->width;
507 
508  krk_long_resize(res, awidth+bwidth);
509  krk_long_zero(res);
510 
511  for (size_t i = 0; i < bwidth; ++i) {
512  uint64_t b_digit = b->digits[i];
513  uint64_t carry = 0;
514  for (size_t j = 0; j < awidth; ++j) {
515  uint64_t a_digit = a->digits[j];
516  uint64_t tmp = carry + a_digit * b_digit + res->digits[i+j];
517  carry = tmp >> DIGIT_SHIFT;
518  res->digits[i+j] = tmp & DIGIT_MAX;
519  }
520  res->digits[i + awidth] = carry;
521  }
522 
523  krk_long_trim(res);
524 
525  return 0;
526 }
527 
533 static int krk_long_mul(KrkLong * res, const KrkLong * a, const KrkLong * b) {
534  PREP_OUTPUT(res,a,b);
535 
536  if (a->width == 0) {
537  krk_long_clear(res);
538  krk_long_init_copy(res,a);
539  FINISH_OUTPUT(res);
540  return 0;
541  }
542 
543  if (b->width == 0) {
544  krk_long_clear(res);
545  krk_long_init_copy(res,b);
546  FINISH_OUTPUT(res);
547  return 0;
548  }
549 
550  if (_mul_abs(res,a,b)) {
551  FINISH_OUTPUT(res);
552  return 1;
553  }
554 
555  if ((a->width < 0) == (b->width < 0)) {
556  krk_long_set_sign(res,1);
557  } else {
558  krk_long_set_sign(res,-1);
559  }
560 
561  FINISH_OUTPUT(res);
562  return 0;
563 }
564 
570 static int _lshift_one(KrkLong * in) {
571  if (in->width == 0) {
572  return 0;
573  }
574 
575  size_t abs_width = in->width < 0 ? -in->width : in->width;
576  size_t out_width = abs_width;
577 
578  if (in->digits[abs_width-1] >> (DIGIT_SHIFT - 1)) {
579  out_width += 1;
580  }
581 
582  krk_long_resize(in, out_width);
583 
584  int carry = 0;
585 
586  for (size_t i = 0; i < abs_width; ++i) {
587  uint32_t digit = in->digits[i];
588  in->digits[i] = ((digit << 1) + carry) & DIGIT_MAX;
589  carry = (digit >> (DIGIT_SHIFT -1));
590  }
591 
592  if (carry) {
593  in->digits[out_width-1] = 1;
594  }
595 
596  return 0;
597 }
598 
606 static size_t _bits_in(const KrkLong * num) {
607  if (num->width == 0) return 0;
608 
609  size_t abs_width = num->width < 0 ? -num->width : num->width;
610 
611  /* Top bit in digits[abs_width-1] */
612  size_t c = 0;
613  uint32_t digit = num->digits[abs_width-1];
614  while (digit) {
615  c++;
616  digit >>= 1;
617  }
618 
619  return c + (abs_width-1) * DIGIT_SHIFT;
620 }
621 
625 static size_t _bit_is_set(const KrkLong * num, size_t bit) {
626  size_t digit_offset = bit / DIGIT_SHIFT;
627  size_t digit_bit = bit % DIGIT_SHIFT;
628  return !!(num->digits[digit_offset] & (1 << digit_bit));
629 }
630 
634 static int _bit_set_zero(KrkLong * num, int val) {
635  if (num->width == 0) {
636  krk_long_clear(num);
637  krk_long_init_si(num, !!val);
638  return 0;
639  }
640 
641  num->digits[0] = (num->digits[0] & ~1) | (!!val);
642  return 0;
643 }
644 
653 static int krk_long_bit_set(KrkLong * num, size_t bit) {
654  size_t abs_width = num->width < 0 ? -num->width : num->width;
655  size_t digit_offset = bit / DIGIT_SHIFT;
656  size_t digit_bit = bit % DIGIT_SHIFT;
657 
658  if (digit_offset >= abs_width) {
659  krk_long_resize(num, digit_offset+1);
660  for (size_t i = abs_width; i < digit_offset + 1; ++i) {
661  num->digits[i] = 0;
662  }
663  }
664 
665  num->digits[digit_offset] |= (1 << digit_bit);
666  return 0;
667 }
668 
680 static int _div_abs(KrkLong * quot, KrkLong * rem, const KrkLong * a, const KrkLong * b) {
681  /* quot = a / b; rem = a % b */
682 
683  /* Zero quotiant and remainder */
684  krk_long_clear(quot);
685  krk_long_clear(rem);
686 
687  if (b->width == 0) return 1; /* div by zero */
688  if (a->width == 0) return 0; /* div of zero */
689 
690  size_t awidth = a->width < 0 ? -a->width : a->width;
691  size_t bwidth = b->width < 0 ? -b->width : b->width;
692 
693  if (bwidth == 1 && b->digits[0] == 1) {
694  krk_long_init_copy(quot, a);
695  krk_long_set_sign(quot, 1);
696  return 0;
697  }
698 
699  if (awidth < bwidth) {
700  krk_long_init_copy(rem, a);
701  krk_long_set_sign(rem, 1);
702  return 0;
703  }
704 
705  KrkLong absa, absb;
706  krk_long_init_copy(&absa, a);
707  krk_long_set_sign(&absa, 1);
708  krk_long_init_copy(&absb, b);
709  krk_long_set_sign(&absb, 1);
710 
711  if (bwidth == 1) {
712  uint64_t remainder = 0;
713  for (size_t i = 0; i < awidth; ++i) {
714  size_t _i = awidth - i - 1;
715  remainder = (remainder << DIGIT_SHIFT) | absa.digits[_i];
716  absa.digits[_i] = (uint32_t)(remainder / absb.digits[0]) & DIGIT_MAX;
717  remainder -= (uint64_t)(absa.digits[_i]) * absb.digits[0];
718  }
719 
720  krk_long_init_si(rem, remainder);
721  _swap(quot, &absa);
722  krk_long_trim(quot);
723 
724  krk_long_clear_many(&absa, &absb, NULL);
725  return 0;
726  }
727 
728  size_t bits = _bits_in(a);
729  for (size_t i = 0; i < bits; ++i) {
730  size_t _i = bits - i - 1;
731 
732  /* Shift remainder by one */
733  _lshift_one(rem);
734 
735  int is_set = _bit_is_set(&absa, _i);
736  _bit_set_zero(rem, is_set);
737  if (krk_long_compare(rem,&absb) >= 0) {
738  _sub_big_small(rem,rem,&absb);
739  krk_long_bit_set(quot, _i);
740  }
741  }
742 
743  krk_long_trim(quot);
744  krk_long_clear_many(&absa,&absb,NULL);
745 
746  return 0;
747 }
748 
759 static int krk_long_div_rem(KrkLong * quot, KrkLong * rem, const KrkLong * a, const KrkLong * b) {
760  PREP_OUTPUT(quot,a,b);
761  PREP_OUTPUT(rem,a,b);
762  if (_div_abs(quot,rem,a,b)) {
763  FINISH_OUTPUT(rem);
764  FINISH_OUTPUT(quot);
765  return 1;
766  }
767 
768  if ((a->width < 0) != (b->width < 0)) {
769  /* Round down if remainder */
770  if (rem->width) {
771  KrkLong one;
772  krk_long_init_si(&one, 1);
773  krk_long_add(quot, quot, &one);
774  _sub_big_small(rem, b, rem);
775  krk_long_clear(&one);
776  }
777 
778  /* Signs are different, negate and round down if necessary */
779  krk_long_set_sign(quot, -1);
780  }
781 
782  if (b->width < 0) {
783  krk_long_set_sign(rem, -1);
784  }
785 
786  FINISH_OUTPUT(rem);
787  FINISH_OUTPUT(quot);
788  return 0;
789 }
790 
796 static int krk_long_abs(KrkLong * out, const KrkLong * in) {
797  PREP_OUTPUT1(out,in);
798  krk_long_clear(out);
799  krk_long_init_copy(out, in);
800  krk_long_set_sign(out, 1);
801  FINISH_OUTPUT(out);
802  return 0;
803 }
804 
810 static int krk_long_sign(const KrkLong * num) {
811  if (num->width == 0) return 0;
812  return num->width < 0 ? -1 : 1;
813 }
814 
821 size_t krk_long_digits_in_base(KrkLong * num, int base) {
822  if (num->width == 0) return 1;
823 
824  size_t bits = _bits_in(num);
825 
826  if (base < 4) return bits;
827  if (base < 8) return (bits+1)/2;
828  if (base < 16) return (bits+2)/3;
829  if (base == 16) return (bits+3)/4;
830  return 0;
831 }
832 
836 static int64_t krk_long_medium(KrkLong * num) {
837  if (num->width == 0) return 0;
838 
839  if (num->width < 0) {
840  uint64_t val = num->digits[0];
841  if (num->width < -1) {
842  val |= (num->digits[1]) << 31;
843  }
844  return -val;
845  } else {
846  uint64_t val = num->digits[0];
847  if (num->width > 1) {
848  val |= (num->digits[1]) << 31;
849  }
850  return val;
851  }
852 }
853 
861 static int do_bin_op(KrkLong * res, const KrkLong * a, const KrkLong * b, char op) {
862  size_t awidth = a->width < 0 ? -a->width : a->width;
863  size_t bwidth = b->width < 0 ? -b->width : b->width;
864  size_t owidth = ((awidth > bwidth) ? awidth : bwidth) + 1;
865 
866  int aneg = (a->width < 0);
867  int bneg = (b->width < 0);
868  int rneg = 0;
869 
870  switch (op) {
871  case '|': rneg = aneg | bneg; break;
872  case '^': rneg = aneg ^ bneg; break;
873  case '&': rneg = aneg & bneg; break;
874  }
875 
876  krk_long_resize(res, owidth);
877 
878  int acarry = aneg ? 1 : 0;
879  int bcarry = bneg ? 1 : 0;
880  int rcarry = rneg ? 1 : 0;
881 
882  for (size_t i = 0; i < owidth; ++i) {
883  uint32_t a_digit = (i < awidth ? a->digits[i] : 0);
884  a_digit = aneg ? ((a_digit ^ DIGIT_MAX) + acarry) : a_digit;
885  acarry = a_digit >> DIGIT_SHIFT;
886 
887  uint32_t b_digit = (i < bwidth ? b->digits[i] : 0);
888  b_digit = bneg ? ((b_digit ^ DIGIT_MAX) + bcarry) : b_digit;
889  bcarry = b_digit >> DIGIT_SHIFT;
890 
891  uint32_t r;
892  switch (op) {
893  case '|': r = a_digit | b_digit; break;
894  case '^': r = a_digit ^ b_digit; break;
895  case '&': r = a_digit & b_digit; break;
896  default: __builtin_unreachable();
897  }
898 
899  r = rneg ? (((r & DIGIT_MAX) ^ DIGIT_MAX) + rcarry) : r;
900  res->digits[i] = r & DIGIT_MAX;
901  rcarry = r >> DIGIT_SHIFT;
902  }
903 
904  krk_long_trim(res);
905 
906  if (rneg) {
907  krk_long_set_sign(res,-1);
908  }
909 
910  return 0;
911 }
912 
916 static int krk_long_or(KrkLong * res, const KrkLong * a, const KrkLong * b) {
917  PREP_OUTPUT(res,a,b);
918  if (a->width == 0) {
919  krk_long_clear(res);
920  krk_long_init_copy(res,b);
921  FINISH_OUTPUT(res);
922  return 0;
923  } else if (b->width == 0) {
924  krk_long_clear(res);
925  krk_long_init_copy(res,a);
926  FINISH_OUTPUT(res);
927  return 0;
928  }
929 
930  int out = do_bin_op(res,a,b,'|');
931  FINISH_OUTPUT(res);
932  return out;
933 }
934 
938 static int krk_long_xor(KrkLong * res, const KrkLong * a, const KrkLong * b) {
939  PREP_OUTPUT(res,a,b);
940  int out = do_bin_op(res,a,b,'^');
941  FINISH_OUTPUT(res);
942  return out;
943 }
944 
948 static int krk_long_and(KrkLong * res, const KrkLong * a, const KrkLong * b) {
949  PREP_OUTPUT(res,a,b);
950  if (a->width == 0) {
951  krk_long_clear(res);
952  krk_long_init_copy(res,a);
953  FINISH_OUTPUT(res);
954  return 0;
955  } else if (b->width == 0) {
956  krk_long_clear(res);
957  krk_long_init_copy(res,b);
958  FINISH_OUTPUT(res);
959  return 0;
960  }
961 
962  int out = do_bin_op(res,a,b,'&');
963  FINISH_OUTPUT(res);
964  return out;
965 }
966 
970 static uint32_t _div_inplace(KrkLong * a, uint32_t base) {
971  if (a->width == 0) {
972  return 0;
973  }
974  size_t awidth = a->width;
975  uint64_t remainder = 0;
976  for (size_t i = 0; i < awidth; ++i) {
977  size_t _i = awidth - i - 1;
978  remainder = (remainder << DIGIT_SHIFT) | a->digits[_i];
979  a->digits[_i] = (uint32_t)(remainder / base) & DIGIT_MAX;
980  remainder -= (uint64_t)(a->digits[_i]) * base;
981  }
982 
983  krk_long_trim(a);
984  return remainder;
985 }
986 
987 static const char _vals[] = "0123456789abcdef";
988 static char * _fast_conversion(const KrkLong * abs, unsigned int bits, char * writer) {
989  uint64_t buf = abs->digits[0];
990  uint32_t cnt = DIGIT_SHIFT;
991  ssize_t ind = 1;
992  uint32_t out = 0;
993 
994  while (ind < abs->width || buf) {
995  if (ind < abs->width && cnt < bits) {
996  buf |= (uint64_t)abs->digits[ind] << (uint64_t)cnt;
997  ind++;
998  cnt += DIGIT_SHIFT;
999  }
1000 
1001  out = buf & ((1 << bits) - 1);
1002  cnt -= bits;
1003  buf >>= bits;
1004 
1005  *writer++ = _vals[out];
1006  }
1007 
1008  return writer;
1009 }
1010 
1014 static char * krk_long_to_str(const KrkLong * n, int _base, const char * prefix, size_t *size, uint32_t *_hash) {
1015  KrkLong abs;
1016 
1017  krk_long_init_si(&abs, 0);
1018  krk_long_abs(&abs, n);
1019 
1020  int sign = krk_long_sign(n); /* -? +? 0? */
1021 
1022  size_t len = (sign == -1 ? 1 : 0) + krk_long_digits_in_base(&abs,_base) + strlen(prefix) + 1;
1023  char * tmp = malloc(len);
1024  char * writer = tmp;
1025 
1026  if (sign == 0) {
1027  *writer++ = '0';
1028  } else {
1029  switch (_base) {
1030  case 2: writer = _fast_conversion(&abs,1,writer); break;
1031  case 4: writer = _fast_conversion(&abs,2,writer); break;
1032  case 8: writer = _fast_conversion(&abs,3,writer); break;
1033  case 16: writer = _fast_conversion(&abs,4,writer); break;
1034  default:
1035  while (krk_long_sign(&abs) > 0) {
1036  uint32_t rem = _div_inplace(&abs,_base);
1037  *writer++ = _vals[rem];
1038  }
1039  }
1040  }
1041 
1042  while (*prefix) { *writer++ = *prefix++; }
1043  if (sign < 0) *writer++ = '-';
1044 
1045  char * rev = malloc(len);
1046  char * out = rev;
1047  uint32_t hash = 0;
1048  while (writer != tmp) {
1049  *out = *--writer;
1050  krk_hash_advance(hash,*out);
1051  out++;
1052  }
1053  *out = '\0';
1054  *_hash = hash;
1055 
1056  free(tmp);
1057 
1058  krk_long_clear(&abs);
1059  *size = strlen(rev);
1060 
1061  return rev;
1062 }
1063 
1064 static const unsigned char _convert_table[256] = {
1065 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
1066 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,255,255,255,255,255,255,
1067 255, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35,255,255,255,255,255,
1068 255, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35,255,255,255,255,255,
1069 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
1070 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
1071 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
1072 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
1073 };
1074 
1075 static int is_valid(int base, uint8_t c) {
1076  return _convert_table[c] < base;
1077 }
1078 
1079 static int convert_digit(uint8_t c) {
1080  return _convert_table[c];
1081 }
1082 
1083 static int is_whitespace(char c) {
1084  /* Same set we use in str.strip() by default */
1085  return (c == ' ' || c == '\t' || c == '\n' || c == '\r');
1086 }
1087 
1096 static int krk_long_parse_string(const char * str, KrkLong * num, unsigned int base, size_t len) {
1097  const char * end = str + len;
1098  const char * c = str;
1099  int sign = 1;
1100 
1101  /* Skip any leading whitespace */
1102  while (c < end && is_whitespace(*c)) c++;
1103 
1104  /* Trim any trailing whitespace */
1105  while (end > c && is_whitespace(end[-1])) end--;
1106 
1107  /* If there's nothing here, that's invalid. */
1108  if (c >= end) {
1109  return 1;
1110  }
1111 
1112  if (*c == '-') {
1113  sign = -1;
1114  c++;
1115  } else if (*c == '+') {
1116  c++;
1117  }
1118 
1119  /* Just a sign is not valid... */
1120  if (c >= end) {
1121  return 1;
1122  }
1123 
1124  /* If base was not specified, accept a prefix. */
1125  if (base == 0) {
1126  base = 10;
1127  if (*c == '0') {
1128  c++;
1129 
1130  if (c == end) {
1131  /* If we saw just '0', that's fine... */
1132  krk_long_init_si(num, 0);
1133  return 0;
1134  }
1135 
1136  if (*c == 'x' || *c == 'X') {
1137  base = 16;
1138  c++;
1139  } else if (*c == 'o' || *c == 'O') {
1140  base = 8;
1141  c++;
1142  } else if (*c == 'b' || *c == 'B') {
1143  base = 2;
1144  c++;
1145  } else {
1146  return 2;
1147  }
1148  }
1149  }
1150 
1151  if (c >= end) {
1152  return 1;
1153  }
1154 
1155  if (base == 1 || base > 36) {
1156  return 2;
1157  }
1158 
1159  krk_long_init_si(num, 0);
1160 
1161  if (base == 2 || base == 4 || base == 8 || base == 16 || base == 32) {
1162  size_t bits = 0;
1163  switch (base) {
1164  case 2: bits = 1; break;
1165  case 4: bits = 2; break;
1166  case 8: bits = 3; break;
1167  case 16:bits = 4; break;
1168  case 32:bits = 5; break;
1169  }
1170  size_t digits = 0;
1171  for (const char * x = c; x < end; ++x) {
1172  if (*x == '_') continue;
1173  if (unlikely(!is_valid(base, *x))) {
1174  krk_long_clear(num);
1175  return 1;
1176  }
1177  digits++;
1178  }
1179 
1180  if (!digits) {
1181  krk_long_clear(num);
1182  return 1;
1183  }
1184 
1185  size_t digit_offset = (digits * bits - 1) / DIGIT_SHIFT;
1186  krk_long_resize(num, digit_offset + 1);
1187 
1188  uint32_t cnt = 0;
1189  uint64_t buf = 0;
1190  const char * x = end;
1191  size_t i = 0;
1192 
1193  while (x != c && x[-1] == '_') x--;
1194 
1195  while (x != c || buf) {
1196  while (cnt < DIGIT_SHIFT && x > c) {
1197  buf |= (uint64_t)convert_digit(x[-1]) << cnt;
1198  cnt += bits;
1199  x--;
1200  while (x != c && x[-1] == '_') x--;
1201  }
1202 
1203  num->digits[i++] = buf & DIGIT_MAX;
1204  cnt -= DIGIT_SHIFT;
1205  buf >>= DIGIT_SHIFT;
1206  }
1207 
1208  krk_long_trim(num);
1209  } else {
1210  KrkLong _base, scratch;
1211  krk_long_init_si(&_base, 0);
1212  krk_long_init_si(&scratch, 0);
1213 
1214  while (c < end && *c) {
1215  uint64_t accum = 0;
1216  uint64_t basediv = 1;
1217  while (c < end && *c && (basediv * base < 0x10000000000000UL)) {
1218  if (*c == '_') { c++; continue; }
1219  if (!is_valid(base, *c)) {
1220  krk_long_clear_many(&_base, &scratch, num, NULL);
1221  return 1;
1222  }
1223 
1224  basediv *= base;
1225  accum *= base;
1226  accum += convert_digit(*c);
1227  c++;
1228  }
1229  krk_long_init_ui(&_base, basediv);
1230  krk_long_mul(num, num, &_base);
1231  krk_long_clear_many(&scratch, &_base, NULL);
1232  krk_long_init_ui(&scratch, accum);
1233  krk_long_add(num, num, &scratch);
1234  }
1235 
1236  krk_long_clear_many(&_base, &scratch, NULL);
1237  }
1238 
1239  if (sign == -1) {
1240  krk_long_set_sign(num, -1);
1241  }
1242 
1243  return 0;
1244 }
1245 
1246 typedef KrkLong krk_long[1];
1247 
1248 struct BigInt {
1249  KrkInstance inst;
1250  krk_long value;
1251 };
1252 
1253 #define AS_long(o) ((struct BigInt *)AS_OBJECT(o))
1254 #define IS_long(o) (krk_isInstanceOf(o, KRK_BASE_CLASS(long)))
1255 
1256 #define CURRENT_CTYPE struct BigInt *
1257 #define CURRENT_NAME self
1258 
1259 static KrkValue make_long(krk_integer_type t) {
1260  struct BigInt * self = (struct BigInt*)krk_newInstance(KRK_BASE_CLASS(long));
1261  krk_push(OBJECT_VAL(self));
1262  krk_long_init_si(self->value, t);
1263  return krk_pop();
1264 }
1265 
1266 static void _long_gcsweep(KrkInstance * self) {
1267  krk_long_clear(((struct BigInt*)self)->value);
1268 }
1269 
1270 #ifndef KRK_NO_FLOAT
1271 KrkValue krk_int_from_float(double val);
1272 #endif
1273 
1274 KRK_StaticMethod(long,__new__) {
1275  FUNCTION_TAKES_AT_MOST(2);
1276  /* Some less likely scenarios */
1277  if (argc < 2) {
1278  return make_long(0);
1279  } else if (IS_INTEGER(argv[1])) {
1280  return make_long(AS_INTEGER(argv[1]));
1281  } else if (IS_BOOLEAN(argv[1])) {
1282  return make_long(AS_BOOLEAN(argv[1]));
1283 #ifndef KRK_NO_FLOAT
1284  } else if (IS_FLOATING(argv[1])) {
1285  return krk_int_from_float(AS_FLOATING(argv[1]));
1286 #endif
1287  } else if (IS_STRING(argv[1])) {
1288  /* XXX This should probably work like int(...) does and default to base 10... and take a base at all... */
1289  struct BigInt * self = (struct BigInt*)krk_newInstance(KRK_BASE_CLASS(long));
1290  krk_push(OBJECT_VAL(self));
1291  if (krk_long_parse_string(AS_CSTRING(argv[1]),self->value,0,AS_STRING(argv[1])->length)) {
1292  return krk_runtimeError(vm.exceptions->valueError, "invalid literal for long() with base 0: %R", argv[1]);
1293  }
1294  return krk_pop();
1295  } else if (IS_long(argv[1])) {
1296  struct BigInt * self = (struct BigInt*)krk_newInstance(KRK_BASE_CLASS(long));
1297  krk_push(OBJECT_VAL(self));
1298  krk_long_init_copy(self->value,AS_long(argv[1])->value);
1299  return krk_pop();
1300  } else {
1301  return krk_runtimeError(vm.exceptions->typeError, "%s() argument must be a string or a number, not '%T'", "int", argv[1]);
1302  }
1303 }
1304 
1305 #ifndef KRK_NO_FLOAT
1314 static double krk_long_get_double(const KrkLong * value) {
1315  size_t awidth = value->width < 0 ? -value->width : value->width;
1316  if (awidth == 0) return 0.0;
1317 
1318  uint64_t sign = value->width < 0 ? 1 : 0;
1319 
1320  /* We only need the top two digits if this value is normalized */
1321  uint64_t mantissa = 0;
1322  uint64_t high = value->digits[awidth-1];
1323  uint64_t med = awidth > 1 ? value->digits[awidth-2] : 0;
1324  uint64_t low = awidth > 2 ? value->digits[awidth-3] : 0;
1325 
1326  int s = 0;
1327  for (s = DIGIT_SHIFT; s >= 0; s--) {
1328  if (high & (1 << s)) break;
1329  }
1330 
1331  int high_shift = 52 - s;
1332  int med_shift = 21 - s;
1333  int low_shift = 10 + s;
1334 
1335  mantissa |= high << high_shift;
1336  mantissa |= med_shift >= 0 ? (med << med_shift) : (med >> -med_shift);
1337  mantissa |= low >> low_shift;
1338 
1339  mantissa &= 0xfffffffffffffUL;
1340 
1341  uint64_t exp = (s + (awidth - 1) * DIGIT_SHIFT) + 0x3FF;
1342 
1343  if (exp > 0x7Fe) {
1344  krk_runtimeError(vm.exceptions->valueError, "overflow, too large for float conversion");
1345  return 0.0;
1346  }
1347 
1348  uint64_t val = (sign << 63) | (exp << 52) | mantissa;
1349 
1350  union { uint64_t asInt; double asDbl; } u = {val};
1351  return u.asDbl;
1352 }
1353 
1354 KRK_Method(long,__float__) {
1355  return FLOATING_VAL(krk_long_get_double(self->value));
1356 }
1357 
1358 static KrkValue _krk_long_truediv(KrkLong * _top, KrkLong * _bottom) {
1359  if (_bottom->width == 0) return krk_runtimeError(vm.exceptions->valueError, "float division by zero");
1360  if (_top->width == 0) return FLOATING_VAL(0);
1361 
1362  KrkLong rem, top, bottom;
1363  krk_long_init_si(&rem, 0);
1364  krk_long_init_copy(&top, _top);
1365  krk_long_init_copy(&bottom, _bottom);
1366 
1367  /* Take sign from original inputs */
1368  int negative = (krk_long_sign(&top) < 0) != (krk_long_sign(&bottom) < 0);
1369 
1370  /* And then make top and bottom absolute */
1371  krk_long_set_sign(&top, 1);
1372  krk_long_set_sign(&bottom, 1);
1373 
1374  /* Final outputs that go into the floats */
1375  uint64_t quot = 0;
1376  long long exp = 0;
1377 
1378 #define NEEDED_BITS 53
1379  int bits_wanted = NEEDED_BITS;
1380  size_t bits = _bits_in(&top);
1381  for (ssize_t i = 0; bits_wanted >= 0; ++i) {
1382  ssize_t _i = bits - i - 1;
1383  _lshift_one(&rem);
1384  _bit_set_zero(&rem, (_i >= 0 ? _bit_is_set(&top, _i) : 0));
1385  if (krk_long_compare(&rem,&bottom) >= 0) {
1386  if (bits_wanted == NEEDED_BITS) {
1387  exp = 1023 + (bits - i - 1);
1388  }
1389  _sub_big_small(&rem,&rem,&bottom);
1390  quot |= (1ULL << bits_wanted);
1391  bits_wanted--;
1392  } else if (bits_wanted != NEEDED_BITS) {
1393  bits_wanted -= 1;
1394  }
1395  }
1396 #undef NEEDED_BITS
1397 
1398  if (exp < 1) quot >>= -exp + 1;
1399  if ((quot & 1) && !(quot & 2)) {
1400  if (rem.width != 0) quot += 2;
1401  } else if (quot & 1) quot += 2;
1402  quot &= ~1;
1403  if (exp < 1) quot <<= -exp + 1;
1404  if (quot & (1ULL << 54)) {
1405  exp++;
1406  quot = (1ULL << 53);
1407  }
1408 
1409  krk_long_clear_many(&rem, &top, &bottom, NULL);
1410 
1411  quot >>= 1;
1412  if (exp > 2046) {
1413  /* Saturated maximum, but not infinity */
1414  quot = 0x1fffffffffffffULL;
1415  exp = 2046;
1416  } else if (exp < 1 && exp >= -52) {
1417  /* Subnormals */
1418  quot >>= -exp+1;
1419  quot |= 0x10000000000000ULL;
1420  exp = 0;
1421  } else if (exp < -52) {
1422  /* Beyond subnormal, truncate to zero */
1423  quot = 0x10000000000000ULL;
1424  exp = 0;
1425  }
1426 
1427  /* Apply sign */
1428  if (negative) exp |= 2048;
1429 
1430  /* Mash bits together to form double */
1431  quot ^= 1ULL << 52;
1432  quot |= exp << 52;
1433  union { double d; uint64_t u; } val = {.u = quot};
1434 
1435  return FLOATING_VAL(val.d);
1436 }
1437 
1438 static KrkValue checked_float_div(double top, double bottom) {
1439  if (unlikely(bottom == 0.0)) return krk_runtimeError(vm.exceptions->valueError, "float division by zero");
1440  return FLOATING_VAL(top/bottom);
1441 }
1442 
1443 KRK_Method(long,__truediv__) {
1444  krk_long tmp;
1445  if (IS_long(argv[1])) krk_long_init_copy(tmp, AS_long(argv[1])->value);
1446  else if (IS_INTEGER(argv[1])) krk_long_init_si(tmp, AS_INTEGER(argv[1]));
1447  else if (IS_FLOATING(argv[1])) return checked_float_div(krk_long_get_double(self->value), AS_FLOATING(argv[1]));
1448  else return NOTIMPL_VAL();
1449  KrkValue result = _krk_long_truediv(self->value,tmp);
1450  krk_long_clear(tmp);
1451  return result;
1452 }
1453 
1454 KRK_Method(long,__rtruediv__) {
1455  krk_long tmp;
1456  if (IS_long(argv[1])) krk_long_init_copy(tmp, AS_long(argv[1])->value);
1457  else if (IS_INTEGER(argv[1])) krk_long_init_si(tmp, AS_INTEGER(argv[1]));
1458  else if (IS_FLOATING(argv[1])) return checked_float_div(AS_FLOATING(argv[1]), krk_long_get_double(self->value));
1459  else return NOTIMPL_VAL();
1460  KrkValue result = _krk_long_truediv(tmp,self->value);
1461  krk_long_clear(tmp);
1462  return result;
1463 }
1464 
1465 static void _krk_long_pow(krk_long out, krk_long a, krk_long b);
1466 static KrkValue make_long_obj(KrkLong * val);
1467 
1473 static KrkValue _krk_long_pow_internal(krk_long a, krk_long b) {
1474  krk_long tmp;
1475  krk_long_init_si(tmp,0);
1476  if (krk_long_sign(b) < 0) {
1477  /* Implement negative exponent by converting to
1478  * 1 / (a ** -b) */
1479  krk_long ex;
1480  krk_long_init_si(ex,0);
1481  krk_long_init_copy(ex,b);
1482  krk_long_set_sign(ex,1);
1483  _krk_long_pow(tmp,a,ex);
1484  krk_long_clear(ex);
1485  krk_long_init_si(ex,1);
1486  KrkValue result = _krk_long_truediv(ex,tmp);
1487  krk_long_clear(ex);
1488  krk_long_clear(tmp);
1489  return result;
1490  }
1491 
1492  _krk_long_pow(tmp,a,b);
1493  return make_long_obj(tmp);
1494 }
1495 
1496 KRK_Method(long,__pow__) {
1497  krk_long tmp;
1498  if (IS_long(argv[1])) krk_long_init_copy(tmp, AS_long(argv[1])->value);
1499  else if (IS_INTEGER(argv[1])) krk_long_init_si(tmp, AS_INTEGER(argv[1]));
1500  else return NOTIMPL_VAL();
1501  KrkValue result = _krk_long_pow_internal(self->value,tmp);
1502  krk_long_clear(tmp);
1503  return result;
1504 }
1505 
1506 KRK_Method(long,__rpow__) {
1507  krk_long tmp;
1508  if (IS_long(argv[1])) krk_long_init_copy(tmp, AS_long(argv[1])->value);
1509  else if (IS_INTEGER(argv[1])) krk_long_init_si(tmp, AS_INTEGER(argv[1]));
1510  else return NOTIMPL_VAL();
1511  KrkValue result = _krk_long_pow_internal(tmp,self->value);
1512  krk_long_clear(tmp);
1513  return result;
1514 }
1515 
1516 _noexport
1517 KrkValue krk_long_coerced_pow(krk_integer_type a, krk_integer_type b) {
1518  krk_long tmp_a, tmp_b;
1519  krk_long_init_si(tmp_a, a);
1520  krk_long_init_si(tmp_b, b);
1521  KrkValue result = _krk_long_pow_internal(tmp_a,tmp_b);
1522  krk_long_clear_many(tmp_a, tmp_b, NULL);
1523  return result;
1524 }
1525 #endif
1526 
1527 #define PRINTER(name,base,prefix) \
1528  KRK_Method(long,__ ## name ## __) { \
1529  size_t size; \
1530  uint32_t hash; \
1531  char * rev = krk_long_to_str(self->value, base, prefix, &size, &hash); \
1532  return OBJECT_VAL(krk_takeStringVetted(rev,size,size,KRK_OBJ_FLAGS_STRING_ASCII,hash)); \
1533  }
1534 
1535 PRINTER(hex,16,"x0")
1536 PRINTER(oct,8,"o0")
1537 PRINTER(bin,2,"b0")
1538 
1539 KRK_Method(long,__hash__) {
1540  return INTEGER_VAL((uint32_t)(krk_long_medium(self->value)));
1541 }
1542 
1543 static KrkValue make_long_obj(KrkLong * val) {
1544  krk_integer_type maybe = 0;
1545  if (val->width == 0) {
1546  maybe = 0;
1547  } else if (val->width == 1) {
1548  maybe = val->digits[0];
1549  } else if (val->width == -1) {
1550  maybe = -(int64_t)val->digits[0];
1551  } else if (val->width == 2 && (val->digits[1] & 0xFFFF0000) == 0) {
1552  maybe = ((uint64_t)val->digits[1] << 31) | val->digits[0];
1553  } else if (val->width == -2 && (val->digits[1] & 0xFFFF0000) == 0) {
1554  maybe = -(((uint64_t)val->digits[1] << 31) | val->digits[0]);
1555  } else {
1556  krk_push(OBJECT_VAL(krk_newInstance(KRK_BASE_CLASS(long))));
1557  *AS_long(krk_peek(0))->value = *val;
1558  return krk_pop();
1559  }
1560 
1561  krk_long_clear(val);
1562  return INTEGER_VAL(maybe);
1563 }
1564 
1565 KrkValue krk_parse_int(const char * start, size_t width, unsigned int base) {
1566  KrkLong _value;
1567  if (krk_long_parse_string(start, &_value, base, width)) {
1568  return NONE_VAL();
1569  }
1570 
1571  return make_long_obj(&_value);
1572 }
1573 
1574 KRK_Method(long,__int__) {
1575  return INTEGER_VAL(krk_long_medium(self->value));
1576 }
1577 
1578 #define BASIC_BIN_OP_FLOATS(name, long_func, MAYBE_FLOAT, MAYBE_FLOAT_INV) \
1579  KRK_Method(long,__ ## name ## __) { \
1580  krk_long tmp; \
1581  if (IS_long(argv[1])) krk_long_init_copy(tmp, AS_long(argv[1])->value); \
1582  else if (IS_INTEGER(argv[1])) krk_long_init_si(tmp, AS_INTEGER(argv[1])); \
1583  MAYBE_FLOAT \
1584  else return NOTIMPL_VAL(); \
1585  long_func(tmp,self->value,tmp); \
1586  return make_long_obj(tmp); \
1587  } \
1588  KRK_Method(long,__r ## name ## __) { \
1589  krk_long tmp; \
1590  if (IS_long(argv[1])) krk_long_init_copy(tmp, AS_long(argv[1])->value); \
1591  else if (IS_INTEGER(argv[1])) krk_long_init_si(tmp, AS_INTEGER(argv[1])); \
1592  MAYBE_FLOAT_INV \
1593  else return NOTIMPL_VAL(); \
1594  long_func(tmp,tmp,self->value); \
1595  return make_long_obj(tmp); \
1596  } \
1597  _noexport \
1598  KrkValue krk_long_coerced_ ## name (krk_integer_type a, krk_integer_type b) { \
1599  krk_long tmp_res, tmp_a, tmp_b; \
1600  krk_long_init_si(tmp_res, 0); \
1601  krk_long_init_si(tmp_a, a); \
1602  krk_long_init_si(tmp_b, b); \
1603  long_func(tmp_res, tmp_a, tmp_b); \
1604  krk_long_clear_many(tmp_a, tmp_b, NULL); \
1605  return make_long_obj(tmp_res); \
1606  }
1607 
1608 #define BASIC_BIN_OP(a,b) BASIC_BIN_OP_FLOATS(a,b,,)
1609 #ifndef KRK_NO_FLOAT
1610 #define FLOAT_A(op) else if (IS_FLOATING(argv[1])) return FLOATING_VAL(krk_long_get_double(self->value) op AS_FLOATING(argv[1]));
1611 #define FLOAT_B(op) else if (IS_FLOATING(argv[1])) return FLOATING_VAL(AS_FLOATING(argv[1]) op krk_long_get_double(self->value));
1612 #else
1613 #define FLOAT_A(op) else if (IS_FLOATING(argv[1])) return krk_runtimeError(vm.exceptions->valueError, "no float support");
1614 #define FLOAT_B(op) else if (IS_FLOATING(argv[1])) return krk_runtimeError(vm.exceptions->valueError, "no float support");
1615 #endif
1616 #define BASIC_BIN_OP_FLOAT(a,b,op) BASIC_BIN_OP_FLOATS(a,b,FLOAT_A(op),FLOAT_B(op))
1617 
1618 BASIC_BIN_OP_FLOAT(add,krk_long_add,+)
1619 BASIC_BIN_OP_FLOAT(sub,krk_long_sub,-)
1620 BASIC_BIN_OP_FLOAT(mul,krk_long_mul,*)
1621 BASIC_BIN_OP(or, krk_long_or)
1622 BASIC_BIN_OP(xor,krk_long_xor)
1623 BASIC_BIN_OP(and,krk_long_and)
1624 
1625 static void _krk_long_lshift_z(krk_long out, krk_long val, size_t amount) {
1626  if (amount == 0) {
1627  krk_long_clear(out);
1628  krk_long_init_copy(out,val);
1629  return;
1630  }
1631 
1632  int64_t count = _bits_in(val);
1633  krk_long_clear(out);
1634  if (count == 0) return;
1635 
1636  size_t offset = amount % 31;
1637  size_t cycles = amount / 31;
1638  ssize_t w = val->width < 0 ? -val->width : val->width;
1639  krk_long_bit_set(out, count - 1 + amount);
1640 
1641  if (!offset) {
1642  for (ssize_t i = 0; i < w; ++i) {
1643  out->digits[i+cycles] = val->digits[i];
1644  }
1645  } else {
1646  uint32_t shift_in = 0;
1647  for (ssize_t i = 0; i < w; ++i) {
1648  out->digits[i+cycles] = ((val->digits[i] << offset) & DIGIT_MAX) | shift_in;
1649  shift_in = (val->digits[i] >> (31 - offset)) & DIGIT_MAX;
1650  }
1651  if (shift_in) {
1652  out->digits[w+cycles] = shift_in;
1653  }
1654  }
1655 
1656  if (krk_long_sign(val) < 0) krk_long_set_sign(out,-1);
1657 }
1658 
1659 static void _krk_long_lshift(krk_long out, krk_long val, krk_long shift) {
1660  if (krk_long_sign(shift) < 0) { krk_runtimeError(vm.exceptions->valueError, "negative shift count"); return; }
1661  int64_t amount = krk_long_medium(shift);
1662  _krk_long_lshift_z(out,val,amount);
1663 }
1664 
1665 static void _krk_long_rshift_z(krk_long out, krk_long val, size_t amount) {
1666  if (amount == 0) {
1667  krk_long_clear(out);
1668  krk_long_init_copy(out,val);
1669  return;
1670  }
1671 
1672  int64_t count = _bits_in(val);
1673  krk_long_clear(out);
1674  if (count == 0) return;
1675 
1676  if (amount < (size_t)count) {
1677  size_t offset = amount % 31;
1678  size_t cycles = amount / 31;
1679  ssize_t w = val->width < 0 ? -val->width : val->width;
1680  krk_long_bit_set(out, count - 1 - amount);
1681 
1682  if (!offset) {
1683  for (ssize_t i = cycles; i < w; ++i) {
1684  out->digits[i-cycles] = val->digits[i];
1685  }
1686  } else {
1687  out->digits[0] = (val->digits[cycles] >> offset) & DIGIT_MAX;
1688  for (size_t i = 1; i < (size_t)out->width; ++i) {
1689  out->digits[i-1] |= (val->digits[i+cycles] << (31 - offset)) & DIGIT_MAX;
1690  out->digits[i] = (val->digits[i+cycles] >> offset) & DIGIT_MAX;
1691  }
1692  if (out->width+cycles < (size_t)w) {
1693  out->digits[out->width-1] |= (val->digits[out->width+cycles] << (31 - offset)) & DIGIT_MAX;
1694  }
1695  }
1696  }
1697 
1698  if (krk_long_sign(val) < 0) {
1699  KrkLong one;
1700  krk_long_init_si(&one, 1);
1701  krk_long_add(out,out,&one);
1702  krk_long_set_sign(out,-1);
1703  krk_long_clear(&one);
1704  }
1705 }
1706 
1707 static void _krk_long_rshift(krk_long out, krk_long val, krk_long shift) {
1708  if (krk_long_sign(shift) < 0) { krk_runtimeError(vm.exceptions->valueError, "negative shift count"); return; }
1709  int64_t amount = krk_long_medium(shift);
1710  _krk_long_rshift_z(out, val, amount);
1711 }
1712 
1713 static void _krk_long_mod(krk_long out, krk_long a, krk_long b) {
1714  if (krk_long_sign(b) == 0) { krk_runtimeError(vm.exceptions->valueError, "integer division or modulo by zero"); return; }
1715  krk_long garbage;
1716  krk_long_init_si(garbage,0);
1717  krk_long_div_rem(garbage,out,a,b);
1718  krk_long_clear(garbage);
1719 }
1720 
1721 static void _krk_long_div(krk_long out, krk_long a, krk_long b) {
1722  if (krk_long_sign(b) == 0) { krk_runtimeError(vm.exceptions->valueError, "integer division or modulo by zero"); return; }
1723  krk_long garbage;
1724  krk_long_init_si(garbage,0);
1725  krk_long_div_rem(out,garbage,a,b);
1726  krk_long_clear(garbage);
1727 }
1728 
1729 static void _krk_long_pow(krk_long out, krk_long a, krk_long b) {
1730  if (krk_long_sign(b) == 0) {
1731  krk_long_clear(out);
1732  krk_long_init_si(out, 1);
1733  return;
1734  }
1735 
1736  if (krk_long_sign(b) < 0) {
1737  krk_runtimeError(vm.exceptions->notImplementedError, "TODO: negative exponent");
1738  return;
1739  }
1740 
1754  PREP_OUTPUT(out,a,b);
1755 
1756  krk_long_clear(out);
1757  krk_long_init_si(out, 1);
1758 
1759  krk_long scratch;
1760  krk_long_init_si(scratch, 0);
1761 
1762  for (ssize_t i = b[0].width-1; i >= 0; --i) {
1763  uint32_t b_i = b[0].digits[i];
1764 
1765  for (size_t j = (uint32_t)1 << (DIGIT_SHIFT-1); j != 0; j >>= 1) {
1766  krk_long_mul(scratch, out, out);
1767  _swap(out, scratch);
1768 
1769  if (b_i & j) {
1770  krk_long_mul(out, out, a);
1771  }
1772 
1773  /* This can take a long time, especially for values that are likely to
1774  * run out of memory for storage, so best to bail on signal early. */
1775  if (krk_currentThread.flags & KRK_THREAD_SIGNALLED) {
1776  krk_long_clear_many(scratch, out, NULL);
1777  /* There's no need to set exception here, the VM will do it on its
1778  * own eventually... */
1779  return;
1780  }
1781  }
1782  }
1783 
1784  krk_long_clear(scratch);
1785  FINISH_OUTPUT(out);
1786 }
1787 
1788 BASIC_BIN_OP(lshift,_krk_long_lshift)
1789 BASIC_BIN_OP(rshift,_krk_long_rshift)
1790 BASIC_BIN_OP(mod,_krk_long_mod)
1791 BASIC_BIN_OP(floordiv,_krk_long_div)
1792 
1793 #ifndef KRK_NO_FLOAT
1794 #define KRK_FLOAT_COMPARE(comp) else if (IS_FLOATING(argv[1])) return BOOLEAN_VAL(krk_long_get_double(self->value) comp AS_FLOATING(argv[1]));
1795 #else
1796 #define KRK_FLOAT_COMPARE(comp)
1797 #endif
1798 
1799 #define COMPARE_OP(name, comp) \
1800  KRK_Method(long,__ ## name ## __) { \
1801  krk_long tmp; \
1802  if (IS_long(argv[1])) krk_long_init_copy(tmp, AS_long(argv[1])->value); \
1803  else if (IS_INTEGER(argv[1])) krk_long_init_si(tmp, AS_INTEGER(argv[1])); \
1804  KRK_FLOAT_COMPARE(comp) \
1805  else return NOTIMPL_VAL(); \
1806  int cmp = krk_long_compare(self->value,tmp); \
1807  krk_long_clear(tmp); \
1808  return BOOLEAN_VAL(cmp comp 0); \
1809  }
1810 
1811 COMPARE_OP(lt, <)
1812 COMPARE_OP(gt, >)
1813 COMPARE_OP(le, <=)
1814 COMPARE_OP(ge, >=)
1815 COMPARE_OP(eq, ==)
1816 
1817 #undef BASIC_BIN_OP
1818 #undef COMPARE_OP
1819 
1820 KRK_Method(long,__len__) {
1821  return INTEGER_VAL(krk_long_sign(self->value));
1822 }
1823 
1824 KRK_Method(long,__invert__) {
1825  KrkLong tmp, one;
1826  krk_long_init_copy(&tmp, self->value);
1827  krk_long_init_si(&one, 1);
1828  krk_long_add(&tmp, &tmp, &one);
1829  krk_long_set_sign(&tmp, tmp.width > 0 ? -1 : 1);
1830  krk_long_clear(&one);
1831  return make_long_obj(&tmp);
1832 }
1833 
1834 KRK_Method(long,__neg__) {
1835  KrkLong tmp;
1836  krk_long_init_copy(&tmp, self->value);
1837  krk_long_set_sign(&tmp, tmp.width > 0 ? -1 : 1);
1838  return make_long_obj(&tmp);
1839 }
1840 
1841 KRK_Method(long,__abs__) {
1842  KrkLong tmp;
1843  krk_long_init_copy(&tmp, self->value);
1844  krk_long_set_sign(&tmp, 1);
1845  return make_long_obj(&tmp);
1846 }
1847 
1848 KRK_Method(long,__pos__) {
1849  return argv[0];
1850 }
1851 
1852 typedef int (*fmtCallback)(void *, int, int *);
1853 KrkValue krk_doFormatString(const char * typeName, KrkString * format_spec, int positive, void * abs, fmtCallback callback, fmtCallback (*prepCallback)(void*,int));
1854 
1855 struct _private {
1856  KrkLong * val;
1857  char * asStr;
1858  char * next;
1859  size_t len;
1860 };
1861 
1862 static int formatLongCallback(void * a, int base, int *more) {
1863  struct _private * val = a;
1864 
1865  if (val->next) {
1866  char c = *val->next;
1867  int out = 0;
1868  if (c >= '0' && c <= '9') out = c - '0';
1869  else if (c >= 'a' && c <= 'f') out = c - 'a' + 10;
1870  if (val->next == val->asStr || *(--val->next) == '-') {
1871  val->next = NULL;
1872  *more = 0;
1873  } else {
1874  *more = 1;
1875  }
1876  return out;
1877  }
1878 
1879  *more = 0;
1880  return 0;
1881 }
1882 
1883 static char * krk_long_to_decimal_str(const KrkLong * value, size_t * len);
1884 static fmtCallback prepLongCallback(void * a, int base) {
1885  struct _private * val = a;
1886  if (base != 10 || (val->val->width > -10 && val->val->width < 10)) {
1887  uint32_t hash = 0;
1888  val->asStr = krk_long_to_str(val->val, base, "", &val->len, &hash);
1889  } else {
1890  val->asStr = krk_long_to_decimal_str(val->val, &val->len);
1891  }
1892  val->next = &val->asStr[val->len-1];
1893  return formatLongCallback;
1894 }
1895 
1896 KRK_Method(long,__format__) {
1897  METHOD_TAKES_EXACTLY(1);
1898  CHECK_ARG(1,str,KrkString*,format_spec);
1899 
1900  struct _private tmp = { self->value, NULL, NULL, 0 };
1901 
1902  KrkValue result = krk_doFormatString("long",format_spec,
1903  krk_long_sign(self->value) >= 0,
1904  &tmp,
1905  NULL,
1906  prepLongCallback);
1907 
1908  if (tmp.asStr) {
1909  free(tmp.asStr);
1910  }
1911 
1912  return result;
1913 }
1914 
1915 static KrkValue long_bit_count(KrkLong * val) {
1916  size_t count = 0;
1917  size_t bits = _bits_in(val);
1918 
1919  for (size_t i = 0; i < bits; ++i) {
1920  count += _bit_is_set(val, i);
1921  }
1922 
1923  KrkLong tmp;
1924  krk_long_init_ui(&tmp, count);
1925  return make_long_obj(&tmp);
1926 }
1927 
1928 KRK_Method(long,bit_count) {
1929  return long_bit_count(self->value);
1930 }
1931 
1932 static KrkValue long_bit_length(KrkLong * val) {
1933  size_t bits = _bits_in(val);
1934  KrkLong tmp;
1935  krk_long_init_ui(&tmp, bits);
1936  return make_long_obj(&tmp);
1937 }
1938 
1939 KRK_Method(long,bit_length) {
1940  return long_bit_length(self->value);
1941 }
1942 
1943 static KrkValue long_to_bytes(KrkLong * val, size_t argc, const KrkValue argv[], int hasKw) {
1944  static const char _method_name[] = "to_bytes";
1945  int length;
1946  const char * byteorder;
1947  int _signed = 0;
1948  if (!krk_parseArgs(".is|p", (const char*[]){"length","byteorder","signed"}, &length, &byteorder, &_signed)) return NONE_VAL();
1949  if (length < 0) return krk_runtimeError(vm.exceptions->valueError, "length must be non-negative");
1950  int order = 0;
1951  if (!strcmp(byteorder,"little")) {
1952  order = 1;
1953  } else if (!strcmp(byteorder,"big")) {
1954  order = -1;
1955  } else {
1956  return krk_runtimeError(vm.exceptions->valueError, "byteorder must be either 'little' or 'big'");
1957  }
1958 
1959  if (krk_long_sign(val) < 0 && !_signed) {
1960  return krk_runtimeError(vm.exceptions->notImplementedError, "can not convert negative value to unsigned");
1961  }
1962 
1963  /* We could avoid the copy for a positive value, but whatever... */
1964  KrkLong tmp;
1965  krk_long_init_ui(&tmp, 0);
1966  krk_long_abs(&tmp, val);
1967 
1968  /* Invert negative values; already checked for signed... */
1969  if (krk_long_sign(val) < 0) {
1970  KrkLong one;
1971  krk_long_init_ui(&one, 1);
1972  krk_long_sub(&tmp, &tmp, &one);
1973  krk_long_clear(&one);
1974  }
1975 
1976  /* Use bits from inverted value */
1977  size_t bitCount = _bits_in(&tmp);
1978 
1979  /* If it is signed, we need to reserve the top bit for the sign;
1980  * eg., (127).to_bytes(1,...,signed=True) is fine, but (128) is not,
1981  * and also (-128) should work, which is taken care of by using the
1982  * inverted value... Also, as a weird special case, 0 still has no
1983  * bits even if 'signed', which allows (0).to_bytes(0,...,signed=True)
1984  * even though that makes no sense to me... */
1985  if (_signed && val->width != 0) bitCount++;
1986 
1987  if ((size_t)length * 8 < bitCount) {
1988  krk_long_clear(&tmp);
1989  /* Should be OverflowError, but we don't have that and I don't care to add it right now */
1990  return krk_runtimeError(vm.exceptions->valueError, "int too big to convert");
1991  }
1992 
1993  /* Allocate bytes for final representation */
1994  krk_push(OBJECT_VAL(krk_newBytes(length, NULL)));
1995  memset(AS_BYTES(krk_peek(0))->bytes, 0, length);
1996 
1997  /* We'll use a 'bit reader':
1998  * - We want 8 bits for each byte.
1999  * - We can collect 31 bits from each digit.
2000  * - If we run out of digits, we're done.
2001  */
2002  ssize_t i = 0;
2003  ssize_t j = 0;
2004 
2005  uint64_t accum = 0;
2006  int32_t remaining = 0;
2007  int break_here = 0;
2008 
2009  while (i < length && !break_here) {
2010  if (remaining < 8) {
2011  if (j < tmp.width) {
2012  accum |= ((uint64_t)tmp.digits[j]) << remaining;
2013  j++;
2014  } else {
2015  break_here = 1;
2016  }
2017  remaining += 31;
2018  }
2019 
2020  uint8_t byte = accum & 0xFF;
2021  accum >>= 8;
2022  remaining -= 8;
2023 
2024  AS_BYTES(krk_peek(0))->bytes[order == 1 ? i : (length - i - 1)] = byte;
2025  i++;
2026  }
2027 
2028  /* If input was negative, at this point we're producing an inverted value;
2029  * we already encoded (|n|-1), so now we just need to bit invert. */
2030  if (krk_long_sign(val) < 0) {
2031  for (size_t i = 0; i < (size_t)length; ++i) {
2032  AS_BYTES(krk_peek(0))->bytes[i] ^= 0xFF;
2033  }
2034  }
2035 
2036  /* We produced a bytes object, so we no longer need the long. */
2037  krk_long_clear(&tmp);
2038  return krk_pop();
2039 }
2040 
2041 KRK_Method(long,to_bytes) {
2042  METHOD_TAKES_AT_LEAST(2);
2043  return long_to_bytes(self->value, argc, argv, hasKw);
2044 }
2045 
2054 KRK_Method(long,_digit_count) {
2055  krk_long result; /* since it's a ssize_t */
2056  krk_long_init_si(result, self->value[0].width);
2057  return make_long_obj(result);
2058 }
2059 
2070 KRK_Method(long,_get_digit) {
2071  METHOD_TAKES_EXACTLY(1);
2072 
2073  KrkLong * _self = self->value;
2074 
2075  size_t abs_width = _self->width < 0 ? -_self->width : _self->width;
2076  size_t index;
2077 
2078  if (IS_INTEGER(argv[1])) {
2079  index = AS_INTEGER(argv[1]);
2080  } else if (IS_long(argv[1])) {
2081  KrkLong * value = AS_long(argv[1])->value;
2082  if (value->width < 0 || value->width > 2) {
2083  return krk_runtimeError(vm.exceptions->indexError, "digit index is invalid");
2084  }
2085  index = krk_long_medium(value);
2086  } else {
2087  return TYPE_ERROR(int,argv[1]);
2088  }
2089 
2090  if (index >= abs_width) {
2091  return krk_runtimeError(vm.exceptions->indexError, "digit index out of range");
2092  }
2093 
2094  return INTEGER_VAL(_self->digits[index]);
2095 }
2096 
2104 typedef uint32_t digit_t;
2105 #define DEC_DIGIT_SIZE sizeof(digit_t)
2106 #define DEC_DIGIT_CNT 9
2107 #define DEC_DIGIT_MAX 1000000000
2108 
2112 static digit_t * dec_add(const digit_t * a, size_t awidth, const digit_t * b, size_t bwidth, size_t * outwidth) {
2113  *outwidth = (awidth > bwidth ? awidth : bwidth) + 1;
2114  digit_t * out = calloc(*outwidth, DEC_DIGIT_SIZE);
2115  int64_t carry = 0;
2116  for (size_t i = 0; i < *outwidth - 1; ++i) {
2117  digit_t n = ((i < awidth) ? a[i] : 0) + ((i < bwidth) ? b[i] : 0) + carry;
2118  out[i] = n % DEC_DIGIT_MAX;
2119  carry = (n >= DEC_DIGIT_MAX);
2120  }
2121  if (carry) {
2122  out[*outwidth-1] = 1;
2123  } else {
2124  *outwidth -= 1;
2125  }
2126 
2127  if (*outwidth == 0) {
2128  *outwidth = 1;
2129  out[0] = 0;
2130  }
2131 
2132  return out;
2133 }
2134 
2138 static void dec_isub(digit_t * a, size_t awidth, const digit_t * b, size_t bwidth) {
2139  int64_t carry = 0;
2140  for (size_t i = 0; i < awidth; ++i) {
2141  int64_t a_digit = (int64_t)((i < awidth) ? a[i] : 0) - carry;
2142  int64_t b_digit = (int64_t)((i < bwidth) ? b[i] : 0);
2143  if (a_digit < b_digit) {
2144  a_digit += DEC_DIGIT_MAX;
2145  carry = 1;
2146  } else {
2147  carry = 0;
2148  }
2149  a[i] = (a_digit - b_digit) % DEC_DIGIT_MAX;
2150  }
2151 }
2152 
2156 static digit_t * dec_shift(const digit_t * a, size_t awidth, size_t amount, size_t * outwidth) {
2157  if (awidth == 1 && a[0] == 0) {
2158  *outwidth = 1;
2159  return calloc(1,DEC_DIGIT_SIZE);
2160  }
2161  *outwidth = awidth + amount;
2162  digit_t * out = calloc(*outwidth,DEC_DIGIT_SIZE);
2163 
2164  for (size_t i = 0; i < awidth; ++i) {
2165  out[i+amount] = a[i];
2166  }
2167 
2168  return out;
2169 }
2170 
2177 static digit_t * dec_mul(const digit_t * a, size_t a_width, const digit_t * b, size_t b_width, size_t * outwidth) {
2178  /* We want a to be bigger than b */
2179  if (a_width < b_width) {
2180  const digit_t * t = a;
2181  a = b;
2182  b = t;
2183  size_t tmp = a_width;
2184  a_width = b_width;
2185  b_width = tmp;
2186  }
2187 
2188  *outwidth = a_width + b_width;
2189 
2190  /* Degenerate case where a or b is 0: return 0 */
2191  if ((a_width == 1 && a[0] == 0) || (b_width == 1 && b[0] == 0)) {
2192  *outwidth = 1;
2193  return calloc(1,DEC_DIGIT_SIZE);
2194  }
2195 
2196  /* Degenerate case where a is 1, return b */
2197  if (a_width == 1 && a[0] == 1) {
2198  *outwidth = b_width;
2199  digit_t * out = malloc(*outwidth * DEC_DIGIT_SIZE);
2200  memcpy(out, b, *outwidth * DEC_DIGIT_SIZE);
2201  return out;
2202  }
2203 
2204  /* Degenerate case where b is 1, return a */
2205  if (b_width == 1 && b[0] == 1) {
2206  *outwidth = a_width;
2207  digit_t * out = malloc(*outwidth * DEC_DIGIT_SIZE);
2208  memcpy(out, a, *outwidth * DEC_DIGIT_SIZE);
2209  return out;
2210  }
2211 
2212  if (b_width < 50) {
2213  /* Fallback brute-force multiplication */
2214  digit_t * out = calloc(*outwidth,DEC_DIGIT_SIZE);
2215  for (size_t i = 0; i < b_width; ++i) {
2216  digit_t bdigit = (i < b_width) ? b[i] : 0;
2217  int64_t carry = 0;
2218  for (size_t j = 0; j < a_width; ++j) {
2219  digit_t adigit = (j < a_width) ? a[j] : 0;
2220  uint64_t t = carry + (int64_t)adigit * (int64_t)bdigit + out[i+j];
2221  carry = t / DEC_DIGIT_MAX;
2222  out[i+j] = t % DEC_DIGIT_MAX;
2223  }
2224  out[i+a_width] = carry;
2225  }
2226  while (*outwidth > 1 && out[(*outwidth)-1] == 0) (*outwidth)--;
2227  return out;
2228  } else {
2229  size_t m2 = a_width / 2;
2230 
2231  /* Split a into its high and low halves */
2232  const digit_t * low1 = a;
2233  size_t low1_width = (m2 <= a_width) ? m2 : a_width;
2234  while (low1_width > 1 && low1[low1_width-1] == 0) low1_width--;
2235  digit_t a_zero = 0;
2236  const digit_t * high1 = (m2 <= a_width) ? (a + m2) : &a_zero;
2237  size_t high1_width = (m2 <= a_width) ? (a_width - m2) : 1;
2238 
2239  /* Split b into its high and low halves */
2240  const digit_t * low2 = b;
2241  size_t low2_width = (m2 <= b_width) ? m2 : b_width;
2242  while (low2_width > 1 && low2[low2_width-1] == 0) low2_width--;
2243  digit_t b_zero = 0;
2244  const digit_t * high2 = (m2 <= b_width) ? (b + m2) : &b_zero;
2245  size_t high2_width = (m2 <= b_width) ? (b_width - m2) : 1;
2246 
2247  size_t z0_width, z1_width, z2_width;
2248 
2249  /* z0 = low1 * low2; z2 = high1 * high2 */
2250  digit_t * z0 = dec_mul(low1, low1_width, low2, low2_width, &z0_width);
2251  digit_t * z2 = dec_mul(high1, high1_width, high2, high2_width, &z2_width);
2252 
2253  /* z1 = (low1 + high1) * (low2 + high2) */
2254  size_t sleft_width, sright_width;
2255  digit_t * sleft = dec_add(low1, low1_width, high1, high1_width, &sleft_width);
2256  digit_t * sright = dec_add(low2, low2_width, high2, high2_width, &sright_width);
2257  digit_t * z1 = dec_mul(sleft, sleft_width, sright, sright_width, &z1_width);
2258  free(sleft);
2259  free(sright);
2260 
2261  /* Store (z1 - z2 - z0) into z1 */
2262  dec_isub(z1, z1_width, z2, z2_width);
2263  dec_isub(z1, z1_width, z0, z0_width);
2264 
2265  /* Calculate (z1 - z2 - z0) * 10 ^ m2 */
2266  size_t m2_shift_width;
2267  digit_t * m2_shift = dec_shift(z1, z1_width, m2, &m2_shift_width);
2268  free(z1);
2269 
2270  /* Add z0 to that */
2271  size_t add_width;
2272  digit_t * add = dec_add(m2_shift, m2_shift_width, z0, z0_width, &add_width);
2273  free(m2_shift);
2274  free(z0);
2275 
2276  /* Then calculate z2 * 10 ^ (m2 * 2) */
2277  size_t m2_2_width;
2278  digit_t * m2_2 = dec_shift(z2, z2_width, m2 * 2, &m2_2_width);
2279  free(z2);
2280 
2281  /* And add everything up */
2282  size_t result_width;
2283  digit_t * result = dec_add(m2_2, m2_2_width, add, add_width, &result_width);
2284  free(m2_2);
2285  free(add);
2286 
2287  *outwidth = result_width;
2288  return result;
2289  }
2290 }
2291 
2310 static digit_t * dec_two_raised(size_t w, size_t * sizeOut) {
2311  if (w <= 29) {
2312  *sizeOut = 1;
2313  digit_t * out = malloc(DEC_DIGIT_SIZE);
2314  out[0] = 1 << w;
2315  return out;
2316  } else {
2317  /* w2 = w >> 1 */
2318  size_t w2 = w >> 1;
2319 
2320  /* t = Decimal(1 << w2) */
2321  size_t tSize;
2322  digit_t * t = dec_two_raised(w2, &tSize);
2323 
2324  if ((w & 1) == 0) {
2325  /* Result = t * t */
2326  digit_t * result = dec_mul(t, tSize, t, tSize, sizeOut);
2327  free(t);
2328  return result;
2329  } else {
2330  /* wmw2 = w - w2 */
2331  size_t wmw2 = w - w2;
2332 
2333  /* right = 1 << wmw2 */
2334  size_t rightSize;
2335  digit_t * right = dec_two_raised(wmw2, &rightSize);
2336 
2337  /* result = t * right */
2338  digit_t * result = dec_mul(t, tSize, right, rightSize, sizeOut);
2339  free(t);
2340  free(right);
2341  return result;
2342  }
2343  }
2344 }
2345 
2357 static digit_t * long_to_dec_inner(KrkLong * n, size_t w, size_t * sizeOut) {
2358  if (n->width == 0) {
2359  *sizeOut = 1;
2360  return calloc(1,DEC_DIGIT_SIZE);
2361  }
2362  if (w <= 29) {
2363  *sizeOut = 1;
2364  digit_t * out = malloc(DEC_DIGIT_SIZE);
2365  out[0] = n->digits[0];
2366  return out;
2367  }
2368 
2369  size_t aSize, bSize, cSize;
2370  digit_t * a, * b, * c;
2371  KrkLong hi, lo, tmp;
2372  krk_long_init_many(&hi, &lo, &tmp, NULL);
2373  /* w2 = w >> 1 */
2374  size_t w2 = w >> 1;
2375  /* hi = n >> w2 */
2376  _krk_long_rshift_z(&hi, n, w2);
2377  /* tmp = hi << w2 */
2378  _krk_long_lshift_z(&tmp, &hi, w2);
2379  /* lo = n - (hi << w2) */
2380  krk_long_sub(&lo, n, &tmp);
2381  krk_long_clear_many(&tmp, NULL);
2382  /* a = Dec(hi) */
2383  a = long_to_dec_inner(&hi, w - w2, &aSize);
2384  krk_long_clear_many(&hi, NULL);
2385  /* b = Dec(1 << w2) */
2386  b = dec_two_raised(w2, &bSize);
2387  /* c = a * b */
2388  c = dec_mul(a, aSize, b, bSize, &cSize);
2389  free(a);
2390  free(b);
2391  /* a = Dec(lo) */
2392  a = long_to_dec_inner(&lo, w2, &aSize);
2393  krk_long_clear_many(&lo,NULL);
2394  /* result = a + c */
2395  digit_t * result = dec_add(a, aSize, c, cSize, sizeOut);
2396  free(a);
2397  free(c);
2398  return result;
2399 }
2400 
2401 static char * krk_long_to_decimal_str(const KrkLong * value, size_t * len) {
2402  /* We can only do this on positive values, but we can re-use the digits
2403  * of the current number while processing, since longs are generally
2404  * not mutable by any other operations. */
2405  KrkLong abs = *value;
2406  int inv = (krk_long_sign(&abs) == -1);
2407  krk_long_set_sign(&abs, 1);
2408 
2409  /* Calculate bit width for halving */
2410  size_t w = _bits_in(&abs);
2411 
2412  /* Convert to big decimal digits */
2413  size_t size;
2414  digit_t * digits = long_to_dec_inner(&abs, w, &size);
2415 
2416  /* Count number of leading zeros */
2417  int leading = 0;
2418  for (size_t j = 0, div = DEC_DIGIT_MAX/10; j < DEC_DIGIT_CNT; j++, div/=10) {
2419  if (((digits[size-1] / div) % 10)) break;
2420  leading += 1;
2421  }
2422 
2423  /* Allocate space for output */
2424  char * out = malloc(size * DEC_DIGIT_CNT + 1 - leading + inv);
2425  char * writer = out;
2426 
2427  /* Write negative sign if original value was negative. */
2428  if (inv) *(writer++) = '-';
2429 
2430  /* Collect digits */
2431  for (size_t i = 0; i < size; ++i) {
2432  for (size_t j = 0, div = DEC_DIGIT_MAX/10; j < DEC_DIGIT_CNT; j++, div/=10) {
2433  if (leading) { leading--; continue; }
2434  *(writer++) = ((digits[size-i-1] / div) % 10) + '0';
2435  }
2436  }
2437  *writer = '\0';
2438 
2439  free(digits);
2440  *len = writer - out;
2441 
2442  return out;
2443 }
2444 
2445 KRK_Method(long,__repr__) {
2446  /* For rather small values (10 was chosen arbitrarily), use the older approach */
2447  size_t len;
2448 
2449  if (self->value->width > -10 && self->value->width < 10) {
2450  uint32_t hash;
2451  char * rev = krk_long_to_str(self->value, 10, "", &len, &hash);
2452  return OBJECT_VAL(krk_takeStringVetted(rev,len,len,KRK_OBJ_FLAGS_STRING_ASCII,hash));
2453  }
2454 
2455  char * out = krk_long_to_decimal_str(self->value, &len);
2456  return OBJECT_VAL(krk_takeString(out, len));
2457 }
2458 
2459 #ifndef KRK_NO_FLOAT
2460 KrkValue krk_int_from_float(double a) {
2461  union { double d; uint64_t u; } val = {.d = a};
2462 
2463  int sign = (val.u >> 63ULL) ? 1 : 0;
2464  int64_t m = val.u & 0x000fffffffffffffULL;
2465  int64_t e = ((val.u >> 52ULL) & 0x7FF) - 0x3FF;
2466 
2467  if (e < 0) return INTEGER_VAL(0);
2468  if (e == 1024) return krk_runtimeError(vm.exceptions->valueError, "can not convert float %s to int", m ? "Nan" : "infinity");
2469  if (e < 47) return INTEGER_VAL((int64_t)a);
2470 
2471  KrkLong _value, _tmp;
2472  krk_long_init_si(&_value, 0x10000000000000ULL | m);
2473  krk_long_init_si(&_tmp, 0);
2474 
2475  if (e > 52) {
2476  _krk_long_lshift_z(&_tmp, &_value, e - 52);
2477  krk_long_clear(&_value);
2478  _value = _tmp;
2479  } else if (e < 52) {
2480  _krk_long_rshift_z(&_tmp, &_value, 52 - e);
2481  krk_long_clear(&_value);
2482  _value = _tmp;
2483  } else {
2484  krk_long_clear(&_tmp);
2485  }
2486 
2487  krk_long_set_sign(&_value, sign == 1 ? -1 : 1);
2488  return make_long_obj(&_value);
2489 }
2490 
2491 #include <assert.h>
2492 
2493 static size_t round_to(char * str, size_t len, size_t actual, size_t digits) {
2494  /* Round the result to just 16 or 17 decimal digits, rounding to even. If
2495  * the actual number of digits was already smaller than that, do nothing. */
2496  if (actual > digits) {
2497  int carry = 0;
2498  if (str[digits] == '5' && ((digits ? str[digits-1] : 0) % 2 == 0)) {
2499  /* Because our decimal representation is exact, we can be sure that
2500  * this correctly rounds halfway to even because we know all of the
2501  * digits after the truncated 5 are zero or non-zero. */
2502  int all_zeros = 1;
2503  for (size_t j = actual - 1; j > digits; j--) {
2504  if (str[j] != '0') {
2505  all_zeros = 0;
2506  break;
2507  }
2508  }
2509  carry = all_zeros ? 0 : 1;
2510  } else if (str[digits] >= '5') {
2511  /* In other cases, round up if necessary. */
2512  carry = 1;
2513  }
2514  size_t i = digits;
2515  while (i && carry) {
2516  /* Propogate carry */
2517  if (str[i-1] - '0' + carry > 9) {
2518  str[i-1] = '0';
2519  carry = 1;
2520  } else {
2521  str[i-1] += carry;
2522  carry = 0;
2523  }
2524  i--;
2525  }
2526  if (carry && i == 0) {
2527  /* Carry results in new digit on left, push all the relevant stuff over. */
2528  for (size_t j = 0; j < digits; ++j) {
2529  str[j+1] = str[j];
2530  }
2531  /* The new digit is always going to be 1. */
2532  str[0] = '1';
2533  /* Adjust length of resulting valid string; b remains the same, as we
2534  * did not remove any trailing digits at this point. */
2535  return 1;
2536  }
2537  }
2538  return 0;
2539 }
2540 
2562 KrkValue krk_double_to_string(double a, unsigned int digits, char formatter, int plus, int forcedigits) {
2563  union { double d; uint64_t u; } val = {.d = a};
2564 
2565  int noexp = (formatter | 0x20) == 'f';
2566  int alwaysexp = (formatter | 0x20) == 'e';
2567  int caps = !(formatter & 0x20);
2568  char expch = caps ? 'E' : 'e';
2569 
2570  /* Extract sign, mantissa, exponent from double, and handle special cases. */
2571  int sign = (val.u >> 63ULL) ? 1 : 0;
2572  int64_t m = val.u & 0x000fffffffffffffULL;
2573  int64_t e = ((val.u >> 52ULL) & 0x7FF) - 0x3FF;
2574  if (e == 1024) {
2575  struct StringBuilder sb = {0};
2576  if (sign && !m) krk_pushStringBuilder(&sb, '-');
2577  else if (plus) krk_pushStringBuilder(&sb, '+');
2578  if (m) krk_pushStringBuilderStr(&sb, caps ? "NAN" : "nan", 3);
2579  else krk_pushStringBuilderStr(&sb, caps ? "INF" : "inf", 3);
2580  return krk_finishStringBuilder(&sb);
2581  }
2582  if (e == -1023 && m == 0) {
2583  struct StringBuilder sb = {0};
2584  if (sign) krk_pushStringBuilder(&sb, '-');
2585  else if (plus) krk_pushStringBuilder(&sb,'+');
2586  krk_pushStringBuilder(&sb, '0');
2587  /* For f/F and e/E, always fill in digits? */
2588  if (digits && (forcedigits || formatter == ' ')) {
2589  krk_pushStringBuilder(&sb, '.');
2590  for (unsigned int i = 0; i < ((formatter == ' ') ? 1 : (digits - ((!noexp && !alwaysexp) ? 1 : 0))); ++i) {
2591  krk_pushStringBuilder(&sb, '0');
2592  }
2593  }
2594  /* Include exponent for e/E */
2595  if (alwaysexp) {
2596  krk_pushStringBuilder(&sb, expch);
2597  krk_pushStringBuilderStr(&sb, "+00", 3);
2598  }
2599  return krk_finishStringBuilder(&sb);
2600  }
2601 
2602  /* We need to cache the decimal versions of each necessary division of 10⁵², if we've not seen them before. */
2603  KrkValue float_decimal_parts = NONE_VAL();
2604  if (!krk_tableGet_fast(&vm.baseClasses->floatClass->methods, S("__decimals__"), &float_decimal_parts)) {
2605  krk_push(OBJECT_VAL(krk_newTuple(54)));
2606  float_decimal_parts = krk_peek(0);
2607 
2608  KrkLong d;
2609  krk_long_parse_string("10000000000000000000000000000000000000000000000000000", &d, 10, 53);
2610 
2611  for (int i = 0; i < 53; ++i) {
2612  AS_TUPLE(float_decimal_parts)->values.values[AS_TUPLE(float_decimal_parts)->values.count++] = make_long_obj(&d);
2613  if (i != 52) {
2614  KrkLong o;
2615  krk_long_init_si(&o,0);
2616  _krk_long_rshift_z(&o,&d,1);
2617  d = o;
2618  }
2619  }
2620 
2621  /* We use 10^31 to add additional digits to ensure right shifting does not result
2622  * in dropped bits when converting the base-2 exponent to base-10. */
2623  KrkLong f;
2624  krk_long_parse_string("10000000000000000000000000000000", &f, 10, 32);
2625  AS_TUPLE(float_decimal_parts)->values.values[AS_TUPLE(float_decimal_parts)->values.count++] = make_long_obj(&f);
2626 
2627  /* Attach to float class. */
2628  krk_attachNamedValue(&vm.baseClasses->floatClass->methods, "__decimals__", float_decimal_parts);
2629  krk_pop();
2630  }
2631 
2632  /* Given that a double takes the form 2ⁿ × m, where either 1.0 ≤ m < 2.0 or
2633  * (for subnormals) 0 < m < 1.0, generate a decimal representation of m as the
2634  * numerator in a fraction with 10⁵² as the denominator. For example, the
2635  * value 123.456 is represented as:
2636  * 2⁶ × 1.9290000000000000479616346638067625463008880615234375
2637  * So we want to have the value:
2638  * 19290000000000000479616346638067625463008880615234375
2639  * The number of decimal digits needed for this is always the same. We'll then
2640  * take that value and apply the base-2 exponent multiplication through shifting
2641  * to get the equivalent multiplier for a base-10 exponent. */
2642  KrkLong c;
2643  if (e == -1023) {
2644  /* For subnormal values, the implicit 1 disappears and the actual exponent value
2645  * is -1022, so instead of initializing our counter to have the leading 1, we start
2646  * with just 0. */
2647  krk_long_init_si(&c,0);
2648  e = -1022;
2649  } else {
2650  /* Otherwise, our decimal representation of the multiplier will start with a 1, so
2651  * start us off with 10⁵² from above. */
2652  krk_long_init_copy(&c, AS_long(AS_TUPLE(float_decimal_parts)->values.values[0])->value);
2653  }
2654 
2655  /* We add up the decimal values for each bit in the mantissa from large to small. */
2656  for (int i = 0; i < 52; ++i) {
2657  if (m & (1ULL << (51 - i))) {
2658  krk_long_add(&c,&c, AS_long(AS_TUPLE(float_decimal_parts)->values.values[i+1])->value);
2659  }
2660  }
2661 
2662  /* At this point, we know that we have 52 decimal digits to the right of the radix point;
2663  * this represents the base-10 exponent of our denominator. We want to maintain an exact
2664  * value for m after turning the base-2 exponent into a base-10 exponent, so if our
2665  * original base-2 exponent is negative, we might need to add more 0s to the end of
2666  * both the top and bottom of the fraction - we'll add to b to account for that. */
2667  int b = 52;
2668 
2669  if (e < 0) {
2670  /* Repeatedly multiply to increase number of decimal digits by 31, until the resulting
2671  * binary representation has enough trailing 0 bits we can shift away the negative
2672  * exponent and still have an exact decimal representation. */
2673  while (1) {
2674  ssize_t i = 0;
2675  while (!_bit_is_set(&c,i)) i++;
2676  if (i >= -e) break;
2677  krk_long_mul(&c,&c,AS_long(AS_TUPLE(float_decimal_parts)->values.values[53])->value);
2678  b += 31;
2679  }
2680  }
2681 
2682  /* Now, finally, shifting our numerator left or right based on the base-2 exponent
2683  * gives us our base-10 equivalent multiplier, multipled by a large power of ten. */
2684  if (e) {
2685  KrkLong o;
2686  krk_long_init_si(&o,0);
2687  if (e < 0) {
2688  _krk_long_rshift_z(&o,&c,-e);
2689  } else {
2690  _krk_long_lshift_z(&o,&c,e);
2691  }
2692  krk_long_clear(&c);
2693  c = o;
2694  }
2695 
2696  /* At this point, c is the numerator in a fraction with 10^b as the denominator, and
2697  * that fraction represents our multiplier in the expression "10^n × m". "n" can be
2698  * determined based on the number of decimal digits in c and the size of b. We no
2699  * longer need our bigints, we want to deal entirely in decimal - so we'll convert
2700  * to a decimal string. */
2701  size_t len = 0;
2702  char * str = krk_long_to_decimal_str(&c, &len);
2703  krk_long_clear(&c);
2704 
2705  /* Significant digits */
2706  size_t actual = len;
2707  while (actual > 1 && str[actual-1] == '0') actual--;
2708 
2709  int ten_exponent = (int)len - b - 1; /* n of e±n */
2710  int print_exponent = 0; /* print e±n */
2711  int whole_digits = ((int)len >= b) ? ten_exponent + 1 : 0; /* digits before radix point */
2712  int missing_digits = (b >= (int)len) ? b - (int)len : 0; /* digits after radix point not in actual */
2713  int trailing_zeros = 0; /* zeros after actual */
2714 
2715  struct StringBuilder sb = {0};
2716 
2717  if (sign) krk_pushStringBuilder(&sb, '-');
2718  else if (plus) krk_pushStringBuilder(&sb, '+');
2719 
2720  if (!alwaysexp && !noexp) {
2721  /* g/G formatter - rounding is for total digits displayed */
2722  if (digits == 0) digits = 1; /* treat precision of 0 as 1 */
2723  if (actual > digits) {
2724  /* There are more digits than we need to show, so round */
2725  int overflowed = round_to(str, len, actual, digits);
2726  if (overflowed) {
2727  /* If we overflowed, our exponent increases */
2728  ten_exponent += 1;
2729  if (ten_exponent) whole_digits++;
2730  }
2731  /* We are going to use exactly the number of digits we have */
2732  actual = digits;
2733  } else {
2734  /* Only add extra zeros if needed */
2735  trailing_zeros = digits - actual;
2736  }
2737 
2738  /* Take any trailing zeros from the number and transfer them into
2739  * "trailing zeros" so we can remove them if we aren't forcing them. */
2740  while (actual > 1 && str[actual-1] == '0') {
2741  actual--;
2742  trailing_zeros++;
2743  }
2744 
2745  /* For small numbers, or very big numbers, switch to exponent notation. */
2746  if (ten_exponent < -4 || ten_exponent >= (int)digits) {
2747  print_exponent = 1;
2748  whole_digits = 1;
2749  missing_digits = 0;
2750  if (!forcedigits) trailing_zeros = 0;
2751  } else if (!forcedigits) {
2752  if (formatter == ' ' && actual <= (size_t)whole_digits) trailing_zeros = 1;
2753  else trailing_zeros = 0;
2754  }
2755  } else if (noexp) {
2756  /* f/F - always use fixed point; determine how to round appropriately */
2757  if (missing_digits > (int)digits) {
2758  actual = whole_digits;
2759  missing_digits = digits;
2760  } else if (missing_digits && missing_digits + actual > digits) {
2761  /* Small number but we have digits on or before the rounding point */
2762  if (round_to(str, len, actual, digits - missing_digits)) missing_digits--;
2763  actual = digits - missing_digits;
2764  } else if (!missing_digits && actual - whole_digits > digits) {
2765  /* Number with no missing digits but still space for rounding */
2766  if (round_to(str, len, actual, digits + whole_digits)) whole_digits++;
2767  actual = digits + whole_digits;
2768  } else if (actual == (size_t)whole_digits) {
2769  /* Number with no significant fractional part */
2770  missing_digits = digits;
2771  } else {
2772  /* Number with possibly not enough digits */
2773  trailing_zeros = digits - (actual + missing_digits);
2774  }
2775  } else if (alwaysexp) {
2776  if (actual > digits) {
2777  if (round_to(str, len, actual, digits + 1)) ten_exponent += 1;
2778  actual = digits + 1;
2779  } else {
2780  trailing_zeros = digits + 1 - actual;
2781  }
2782  print_exponent = 1;
2783  whole_digits = 1;
2784  missing_digits = 0;
2785  }
2786 
2787  if (!whole_digits) krk_pushStringBuilder(&sb,'0');
2788  else krk_pushStringBuilderStr(&sb,str,whole_digits);
2789  if (forcedigits || actual > (size_t)whole_digits || trailing_zeros) krk_pushStringBuilder(&sb, '.');
2790  if (missing_digits) for (int i = 0; i < missing_digits; ++i) krk_pushStringBuilder(&sb, '0');
2791  if (actual > (size_t)whole_digits) krk_pushStringBuilderStr(&sb, str + whole_digits, actual - whole_digits);
2792  for (int i = 0; i < trailing_zeros; ++i) krk_pushStringBuilder(&sb, '0');
2793 
2794  if (print_exponent) {
2795  char expsign = ten_exponent < 0 ? '-' : '+';
2796  int abs_ten_exponent = ten_exponent < 0 ? -ten_exponent : ten_exponent;
2797  krk_pushStringBuilderFormat(&sb, "%c%c%s%d",
2798  expch, expsign, abs_ten_exponent < 10 ? "0" : "", abs_ten_exponent);
2799  }
2800 
2801  free(str);
2802  return krk_finishStringBuilder(&sb);
2803 }
2804 
2820 KrkValue krk_parse_float(const char * s, size_t l) {
2821  size_t c = 0;
2822  int sign = 1;
2823  size_t ps = 0, pe = 0, ss = 0, se = 0, es = 0, ee = 0, e_ex = 0;
2824 
2825  union Float { double d; uint64_t i; };
2826 
2827  while (c < l && (s[c] == ' ' || s[c] == '\t' || s[c] == '\n' || s[c] == '\r')) c++;
2828 
2829  /* Collect a leading sign. */
2830  if (s[c] == '-') {
2831  sign = -1;
2832  c++;
2833  } else if (s[c] == '+') {
2834  c++;
2835  }
2836  ps = c;
2837 
2838  /* Case-insensitive check for stringy floats: nan, inf */
2839  if (c + 3 == l) {
2840  if (((s[c+0] | 0x20) == 'n') && ((s[c+1] | 0x20) == 'a') && ((s[c+2] | 0x20) == 'n')) {
2841  return FLOATING_VAL(((union Float){.i=0x7ff0000000000001ULL}).d); /* nan */
2842  }
2843  if (((s[c+0] | 0x20) == 'i') && ((s[c+1] | 0x20) == 'n') && ((s[c+2] | 0x20) == 'f')) {
2844  return FLOATING_VAL(((union Float){.i=0x7ff0000000000000ULL}).d * sign); /* inf */
2845  }
2846  }
2847 
2848  /* Collect digits or separators before a radix point. */
2849  while (c < l && ((s[c] >= '0' && s[c] <= '9') || s[c] == '_')) c++;
2850  pe = c;
2851 
2852  /* If we are now at a radix point, collect it and then collect digits after the radix point. */
2853  if (c < l && s[c] == '.') {
2854  c++;
2855  ss = c;
2856  while (c < l && s[c] >= '0' && s[c] <= '9') c++;
2857  se = c;
2858  }
2859 
2860  /* If we're still not at the end, we expect an exponent. */
2861  if (c < l && (s[c] == 'e' || s[c] == 'E')) {
2862  c++;
2863  es = c;
2864  /* The exponent can have an optional sign character, which we'll
2865  * include in the string if it is - and ignore if it is + */
2866  if (c < l && s[c] == '-') c++;
2867  else if (c < l && s[c] == '+') { c++; es++; }
2868 
2869  /* Digits of exponent */
2870  while (c < l && s[c] >= '0' && s[c] <= '9') c++;
2871  ee = c;
2872  }
2873 
2874  while (c < l && (s[c] == ' ' || s[c] == '\t' || s[c] == '\n' || s[c] == '\r')) c++;
2875 
2876  /* If we're not at the end here, we have invalid characters. */
2877  if (c != l) return krk_runtimeError(vm.exceptions->valueError, "invalid literal for float");
2878 
2879  /* We can reduce the work we need to do later if we account for leading 0s in are
2880  * number here. First strip all of the leading zeros from the whole part; if that
2881  * results in no whole part, then continue stripping zeros from the fractional part,
2882  * but be sure to record how many we're removing so we can account for the difference. */
2883  while (ps != pe && s[ps] == '0') ps++;
2884  if (ps == pe) {
2885  while (ss != se && s[ss] == '0') {
2886  e_ex++;
2887  ss++;
2888  }
2889  }
2890 
2891  /* Pack up all the digits from whole and fractional parts into a string so we can parse
2892  * it with our faster decimal string parsing tools. */
2893  struct StringBuilder sb = {0};
2894  for (size_t i = ps; i < pe; ++i) {
2895  if (!sb.length && s[i] == '0') continue;
2896  if (s[i] == '_') continue;
2897  krk_pushStringBuilder(&sb,s[i]);
2898  }
2899  for (size_t i = ss; i < se; ++i) {
2900  if (!sb.length && s[i] == '0') continue;
2901  krk_pushStringBuilder(&sb,s[i]);
2902  }
2903 
2904  /* If that results in an empty string (because we stripped all of the zeros, and it was
2905  * only zeros), then replace it with "0" or the parser will be unhappy. */
2906  const char * m = sb.bytes;
2907  size_t m_len = sb.length;
2908  if (!sb.length) {
2909  m = "0";
2910  m_len = 1;
2911  }
2912 
2913  /* Now parse it. We call this resulting value "m" because it's the numerator of the
2914  * mantissa fraction of a decimal float, if that makes any sense. */
2915  KrkLong m_l;
2916  krk_long_parse_string(m,&m_l,10,m_len);
2918 
2919  /* We didn't include the leading - in our string to parse, so we still want to apply
2920  * the sign to the resulting big int. */
2921  krk_long_set_sign(&m_l,sign);
2922 
2923  /* Handle an exponent component if one exists, or assume 0 otherwise. */
2924  const char * e = (es != ee) ? &s[es] : "0";
2925  size_t e_len = (es != ee) ? (ee-es) : 1;
2926 
2927  /* And parse that into a big int */
2928  KrkLong e_l;
2929  krk_long_parse_string(e,&e_l,10,e_len);
2930 
2931  /* We don't actually want to deal with big ints in the exponent, so assume
2932  * they are going to overflow without even bothering to check to the part
2933  * before them. Overflow to signed infinity or zero. */
2934  if (e_l.width > 1) {
2935  krk_long_clear_many(&m_l,&e_l,NULL);
2936  return FLOATING_VAL(((union Float){.i=0x7ff0000000000000ULL}).d * sign); /* inf */
2937  } else if (e_l.width < -1) {
2938  krk_long_clear_many(&m_l,&e_l,NULL);
2939  return FLOATING_VAL(0.0 * sign);
2940  }
2941 
2942  /* Extract the big int exponent back into a normal integer */
2943  int64_t exp = krk_long_medium(&e_l);
2944  ssize_t digits = (se - ss + e_ex) - exp;
2945 
2946  /* Now do a more accurate check of overflowing exponents before continuing,
2947  * to avoid very costly math to get the answer from truediv. */
2948  if (exp + (ssize_t)(pe - ps) - (ssize_t)e_ex > 309) {
2949  krk_long_clear_many(&m_l,&e_l,NULL);
2950  return FLOATING_VAL(((union Float){.i=0x7ff0000000000000ULL}).d * sign); /* inf */
2951  } else if (exp + (ssize_t)(pe - ps) - (ssize_t)e_ex < -324) {
2952  krk_long_clear_many(&m_l,&e_l,NULL);
2953  return FLOATING_VAL(0.0 * sign);
2954  }
2955 
2956  if (digits > 0) {
2957  /* If digits > 0, exponent is effectively negative. Calculate the result as:
2958  * m / (10 ** digits) */
2959  KrkLong ten_digits, digits_el;
2960  krk_long_init_si(&ten_digits, 10);
2961  krk_long_init_si(&digits_el, digits);
2962  _krk_long_pow(&ten_digits,&ten_digits,&digits_el);
2963  KrkValue v = _krk_long_truediv(&m_l, &ten_digits);
2964  krk_long_clear_many(&digits_el,&m_l,&e_l,&ten_digits, NULL);
2965  return v;
2966  } else if (digits < 0) {
2967  /* If digits < 0, exponent is effectively positive. Calculate the result as:
2968  * (m * (10 ** -digits)) / 1 */
2969  KrkLong ten_digits, digits_el, one;
2970  krk_long_init_si(&ten_digits, 10);
2971  krk_long_init_si(&digits_el, -digits);
2972  krk_long_init_si(&one, 1);
2973  _krk_long_pow(&ten_digits,&ten_digits,&digits_el);
2974  krk_long_mul(&m_l,&m_l,&ten_digits);
2975  KrkValue v = _krk_long_truediv(&m_l, &one);
2976  krk_long_clear_many(&digits_el,&m_l,&e_l,&ten_digits,&one,NULL);
2977  return v;
2978  } else {
2979  /* If digits == 0, exponent is 0, we have only a whole component in m, so
2980  * we only need to do (m / 1) */
2981  KrkLong one;
2982  krk_long_init_si(&one, 1);
2983  KrkValue v = _krk_long_truediv(&m_l, &one);
2984  krk_long_clear_many(&m_l,&e_l,&one,NULL);
2985  return v;
2986  }
2987 }
2988 
2999  uint64_t x = ((union Float { double d; uint64_t i; }){.d=d}).i;
3000 
3001  uint64_t m = x & 0x000fffffffffffffULL;
3002  uint64_t e = ((x >> 52) & 0x7FF);
3003 
3004  if (e) {
3005  /* If not subnormal, include hidden bit 53 */
3006  m |= (1ULL << 52);
3007  } else if (m) {
3008  /* If subnormal and not zero, increase e to correct value */
3009  e++;
3010  }
3011 
3012  krk_long a, b;
3013 
3014  /* NaN or Inf */
3015  if (e == 0x7FF) return krk_runtimeError(vm.exceptions->valueError, "unrepresentable");
3016  if (e == 0) {
3017  /* Python doesn't set a sign to represent this, so we won't either. */
3018  krk_long_init_ui(a, 0);
3019  krk_long_init_ui(b, 1);
3020  goto _finish;
3021  }
3022 
3023  krk_long_init_ui(a, m);
3024  krk_long_init_ui(b, (1ULL << 52));
3025 
3026  /* Generate the numerator and denominator of the complete fraction */
3027  if (e > 0x3FF) {
3028  krk_long tmp;
3029  krk_long_init_ui(tmp, 0);
3030  _krk_long_lshift_z(tmp,a,e-0x3FF);
3031  krk_long_clear(a);
3032  memcpy(&a,&tmp,sizeof(krk_long));
3033  } else if (e < 0x3FF) {
3034  krk_long tmp;
3035  krk_long_init_ui(tmp, 0);
3036  _krk_long_lshift_z(tmp,b,0x3FF-e);
3037  krk_long_clear(b);
3038  memcpy(&b,&tmp,sizeof(krk_long));
3039  }
3040 
3041  /* Slowly reduce the fraction to something reasonable;
3042  * given that one or the other of the top or bottom is
3043  * unshifted, we should be doing this at most ~50 times
3044  * so it doesn't really matter much; we _could_ count
3045  * the common trailing zero bits first and do one shift... */
3046  while (!_bit_is_set(a,0) && !_bit_is_set(b,0)) {
3047  krk_long tmpa, tmpb;
3048  krk_long_init_ui(tmpa, 0);
3049  krk_long_init_ui(tmpb, 0);
3050 
3051  _krk_long_rshift_z(tmpa, a, 1);
3052  _krk_long_rshift_z(tmpb, b, 1);
3053 
3054  krk_long_clear(a);
3055  krk_long_clear(b);
3056 
3057  memcpy(&a,&tmpa,sizeof(krk_long));
3058  memcpy(&b,&tmpb,sizeof(krk_long));
3059  }
3060 
3061  /* Set sign of a to match sign of float */
3062  krk_long_set_sign(a, d < 0 ? -1 : 1);
3063 
3064  /* Stuff it in a tuple */
3065 _finish: (void)0;
3066  KrkTuple * mtuple = krk_newTuple(2);
3067  krk_push(OBJECT_VAL(mtuple));
3068  mtuple->values.values[mtuple->values.count++] = make_long_obj(a);
3069  mtuple->values.values[mtuple->values.count++] = make_long_obj(b);
3070  return krk_pop();
3071 }
3072 #endif
3073 
3083 _protected
3084 int krk_long_to_int(KrkValue val, char size, void * out) {
3085  uint64_t accum = 0;
3086  if (IS_INTEGER(val)) {
3087  /* For integers, there's nothing to do until we want to start
3088  * doing overflow checking, so just extend to 64-bit. */
3089  accum = AS_INTEGER(val);
3090  } else if (IS_long(val)) {
3091  /* For longs, we have some additional work. */
3092  struct BigInt * self = (void*)AS_OBJECT(val);
3093  KrkLong * this = self->value;
3094  size_t swidth = this->width < 0 ? -this->width : this->width;
3095 
3096  if (swidth > 0) {
3097  /* Collect up to three digits worth of bits, to the maximum
3098  * we support of 64. 31, 31, and 2. */
3099  accum |= (uint64_t)this->digits[0];
3100  if (swidth > 1) {
3101  accum |= (uint64_t)this->digits[1] << DIGIT_SHIFT;
3102  if (swidth > 2) {
3103  accum |= (uint64_t)(this->digits[2] & 0x3) << DIGIT_SHIFT * 2;
3104  }
3105  }
3106  /* If this is a negative value, convert the result to twos-complement. */
3107  if (this->width < 0) {
3108  accum -= 1;
3109  accum ^= 0xFFFFffffFFFFffff;
3110  }
3111  }
3112 #ifndef KRK_NO_FLOAT
3113  } else if (IS_FLOATING(val)) {
3114  krk_push(krk_int_from_float(AS_FLOATING(val)));
3115  int res = krk_long_to_int(krk_peek(0), size, out);
3116  krk_pop();
3117  return res;
3118 #endif
3119  } else {
3120  krk_runtimeError(vm.exceptions->typeError, "expected %s, not '%T'", "int", val);
3121  return 0;
3122  }
3123 
3124  /* Now copy over the output. */
3125  switch (size) {
3126  case sizeof(uint8_t): *(uint8_t*)out = accum; break;
3127  case sizeof(uint16_t): *(uint16_t*)out = accum; break;
3128  case sizeof(uint32_t): *(uint32_t*)out = accum; break;
3129  case sizeof(uint64_t): *(uint64_t*)out = accum; break;
3130  default:
3131  krk_runtimeError(vm.exceptions->SystemError, "invalid size");
3132  return 0;
3133  }
3134 
3135  return 1;
3136 }
3137 
3138 
3139 #undef CURRENT_CTYPE
3140 #define CURRENT_CTYPE krk_integer_type
3141 
3148 KRK_Method(int,bit_count) {
3149  krk_long value;
3150  krk_long_init_si(value, self);
3151  KrkValue out = long_bit_count(value);
3152  krk_long_clear(value);
3153  return out;
3154 }
3155 
3156 KRK_Method(int,bit_length) {
3157  krk_long value;
3158  krk_long_init_si(value, self);
3159  KrkValue out = long_bit_length(value);
3160  krk_long_clear(value);
3161  return out;
3162 }
3163 
3164 KRK_Method(int,to_bytes) {
3165  krk_long value;
3166  krk_long_init_si(value, self);
3167  KrkValue out = long_to_bytes(value, argc, argv, hasKw);
3168  krk_long_clear(value);
3169  return out;
3170 }
3171 
3172 #undef BIND_METHOD
3173 #undef BIND_STATICMETHOD
3174 /* These class names conflict with C types, so we need to cheat a bit */
3175 #define BIND_METHOD(klass,method) do { krk_defineNative(& _ ## klass->methods, #method, _ ## klass ## _ ## method); } while (0)
3176 #define BIND_STATICMETHOD(klass,method) do { krk_defineNativeStaticMethod(& _ ## klass->methods, #method, _ ## klass ## _ ## method); } while (0)
3177 #define BIND_TRIPLET(klass,name) \
3178  BIND_METHOD(klass,__ ## name ## __); \
3179  BIND_METHOD(klass,__r ## name ## __); \
3180  krk_defineNative(&_ ## klass->methods,"__i" #name "__",_ ## klass ## ___ ## name ## __);
3181 _noexport
3182 void _createAndBind_longClass(void) {
3183  KrkClass * _long = ADD_BASE_CLASS(vm.baseClasses->longClass, "long", vm.baseClasses->intClass);
3184  _long->obj.flags |= KRK_OBJ_FLAGS_NO_INHERIT;
3185  _long->allocSize = sizeof(struct BigInt);
3186  _long->_ongcsweep = _long_gcsweep;
3187 
3188  BIND_STATICMETHOD(long,__new__);
3189  BIND_METHOD(long,__repr__);
3190  BIND_METHOD(long,__eq__);
3191  BIND_METHOD(long,__hash__);
3192  BIND_METHOD(long,__hex__);
3193  BIND_METHOD(long,__oct__);
3194  BIND_METHOD(long,__bin__);
3195  BIND_METHOD(long,__int__);
3196  BIND_METHOD(long,__len__);
3197  BIND_METHOD(long,__pos__);
3198 
3199  BIND_TRIPLET(long,add);
3200  BIND_TRIPLET(long,sub);
3201  BIND_TRIPLET(long,mul);
3202  BIND_TRIPLET(long,or);
3203  BIND_TRIPLET(long,xor);
3204  BIND_TRIPLET(long,and);
3205  BIND_TRIPLET(long,lshift);
3206  BIND_TRIPLET(long,rshift);
3207  BIND_TRIPLET(long,mod);
3208  BIND_TRIPLET(long,floordiv);
3209  BIND_TRIPLET(long,pow);
3210 
3211 #ifndef KRK_NO_FLOAT
3212  BIND_METHOD(long,__float__);
3213  BIND_TRIPLET(long,truediv);
3214 #endif
3215 
3216  BIND_METHOD(long,__lt__);
3217  BIND_METHOD(long,__gt__);
3218  BIND_METHOD(long,__le__);
3219  BIND_METHOD(long,__ge__);
3220  BIND_METHOD(long,__invert__);
3221  BIND_METHOD(long,__neg__);
3222  BIND_METHOD(long,__abs__);
3223  BIND_METHOD(long,__format__);
3224 
3225  BIND_METHOD(long,bit_count);
3226  BIND_METHOD(long,bit_length);
3227  BIND_METHOD(long,to_bytes);
3228 
3229  /* Internal methods for inspecting longs. Since these are internal,
3230  * we don't bother binding them for ints. */
3231  BIND_METHOD(long,_digit_count);
3232  BIND_METHOD(long,_get_digit);
3233 
3234  krk_finalizeClass(_long);
3235 
3236  /* Patch in small int versions */
3237  KrkClass * _int = vm.baseClasses->intClass;
3238  BIND_METHOD(int,bit_count);
3239  BIND_METHOD(int,bit_length);
3240  BIND_METHOD(int,to_bytes);
3241 
3242 }
3243 
3244 
KrkValue krk_runtimeError(KrkClass *type, const char *fmt,...)
Produce and raise an exception with a formatted message.
Definition: exceptions.c:460
KrkValue krk_parse_float(const char *s, size_t l)
Parse a string into a float.
Definition: obj_long.c:2820
uint32_t digit_t
Definition: obj_long.c:2104
_protected int krk_long_to_int(KrkValue val, char size, void *out)
Convert an int or long to a C integer.
Definition: obj_long.c:3084
size_t krk_long_digits_in_base(KrkLong *num, int base)
Estimate how many digits are needed to convert a long to a base.
Definition: obj_long.c:821
KrkValue krk_double_to_string(double a, unsigned int digits, char formatter, int plus, int forcedigits)
Convert a double to a KrkString.
Definition: obj_long.c:2562
KrkValue krk_float_to_fraction(double d)
Convert a double to a tuple of two longs.
Definition: obj_long.c:2998
Internal header.
KrkBytes * krk_newBytes(size_t length, uint8_t *source)
Create a new byte array.
Definition: object.c:367
Type object.
Definition: object.h:215
KrkCleanupCallback _ongcsweep
C function to call when the garbage collector is discarding an instance of this class.
Definition: object.h:224
size_t allocSize
Size to allocate when creating instances of this class.
Definition: object.h:222
KrkObj obj
Base.
Definition: object.h:216
void krk_finalizeClass(KrkClass *_class)
Finalize a class by collecting pointers to core methods.
Definition: vm.c:189
An object of a class.
Definition: object.h:281
KrkInstance * krk_newInstance(KrkClass *_class)
Create a new instance of the given class.
Definition: object.c:343
uint16_t flags
General object flags, mostly related to garbage collection.
Definition: object.h:43
Immutable sequence of Unicode codepoints.
Definition: object.h:93
KrkString * krk_takeString(char *chars, size_t length)
Yield ownership of a C string to the GC and obtain a string object.
Definition: object.c:208
KrkString * krk_takeStringVetted(char *chars, size_t length, size_t codesLength, KrkStringType type, uint32_t hash)
Like krk_takeString but for when the caller has already calculated code lengths, hash,...
Definition: object.c:241
void krk_attachNamedValue(KrkTable *table, const char name[], KrkValue obj)
Attach a value to an attribute table.
Definition: vm.c:794
int krk_tableGet_fast(KrkTable *table, struct KrkString *str, KrkValue *value)
Obtain the value associated with a string key in a table.
Definition: table.c:219
int flags
Definition: vm.h:165
Immutable sequence of arbitrary values.
Definition: object.h:323
KrkValueArray values
Stores the length, capacity, and actual values of the tuple.
Definition: object.h:325
KrkTuple * krk_newTuple(size_t length)
Create a new tuple.
Definition: object.c:357
KrkValue * values
Definition: value.h:78
size_t count
Definition: value.h:77
Stack reference or primative value.
Inline flexible string array.
Definition: util.h:162
Utilities for creating native bindings.
void krk_pushStringBuilderStr(struct StringBuilder *sb, const char *str, size_t len)
Append a string to the end of a string builder.
Definition: obj_str.c:1091
#define krk_parseArgs(f, n,...)
Parse arguments to a function while accepting keyword arguments.
Definition: util.h:360
KrkValue krk_discardStringBuilder(struct StringBuilder *sb)
Discard the contents of a string builder.
Definition: obj_str.c:1123
KrkValue krk_finishStringBuilder(struct StringBuilder *sb)
Finalize a string builder into a string object.
Definition: obj_str.c:1111
void krk_pushStringBuilder(struct StringBuilder *sb, char c)
Add a character to the end of a string builder.
Definition: obj_str.c:1082
Definitions for primitive stack references.
Core API for the bytecode virtual machine.
krk_threadLocal KrkThreadState krk_currentThread
Thread-local VM state.
#define vm
Convenience macro for namespacing.
Definition: vm.h:257
KrkValue krk_pop(void)
Pop the top of the stack.
Definition: vm.c:131
void krk_push(KrkValue value)
Push a stack value.
Definition: vm.c:118
KrkValue krk_peek(int distance)
Peek down from the top of the stack.
Definition: vm.c:139