Page 239 - ARM 64 Bit Assembly Language
P. 239
Integer mathematics 227
636 bigint r = (bigint) malloc(sizeof(struct bigint_struct));
637 if (r == NULL) {
638 perror("bigint_alloc");
639 exit(1);
640 }
641 r->size = chunks;
642 r->blks = (chunk*) malloc(chunks * sizeof(chunk));
643 if (r->blks == NULL) {
644 perror("bigint_alloc");
645 exit(1);
646 }
647 return r;
648 }
649
650 static bigint bigint_trim(bigint b) {
651 bigint d;
652 int i = b->size-1;
653 if (i > 0) {
654 if (b->blks[i] == 0) {
655 // we have a leading block that is all 0
656 do
657 i--; // search for first block that is not all 0
658 while ((i > 0) && (b->blks[i] == 0));
659 if (b->blks[i] & ((bigchunk)1<<(BITSPERCHUNK-1)))
660 i++; // if msb of current block is 1, then we went too far
661 }
662 else if (b->blks[i] == CHUNKMASK) {
663 // we have a leading block that is all 1
664 do
665 i--; // search for first block that is not all 1
666 while ((i>0) && (b->blks[i]==CHUNKMASK));
667 if (!(b->blks[i] & ((bigchunk)1<<(BITSPERCHUNK-1))))
668 i++; // if msb of current block is 0, then we went too far
669 }
670 }
671 i++; // i is now the number of blocks to copy
672 if (i < b->size) {
673 d = bigint_alloc(i);
674 memcpy(d->blks,b->blks,d->size*sizeof(chunk));
675 } else {
676 d = bigint_copy(b);
677 }
678 return d;
679 }
680
681 /* smallmod divides a bigint by a small number
682 and returns the modulus. b changes as a SIDE-EFFECT.
683 This is used by the to_str function. */
684 static unsigned bigint_smallmod(bigint b, chunk num) {