~ubuntu-branches/ubuntu/trusty/mit-scheme/trusty

« back to all changes in this revision

Viewing changes to src/microcode/bignum.c

  • Committer: Package Import Robot
  • Author(s): Chris Hanson
  • Date: 2011-10-15 03:08:33 UTC
  • mfrom: (1.1.8) (3.1.7 sid)
  • Revision ID: package-import@ubuntu.com-20111015030833-x7qc6yxuulvxbafv
Tags: 9.1-1
* New upstream.
* debian/control, debian/copyright, debian/mit-scheme-doc.*,
  debian/mit-scheme.install, debian/rules, Upstream has removed cover
  texts from documentation licenses, so merge packages mit-scheme and
  mit-scheme-doc back together.
* debian/compat: Bump to current version.
* debian/control: Bump standards-version to current and make
  necessary changes.
* debian/rules: Fix lintian warnings.

Show diffs side-by-side

added added

removed removed

Lines of Context:
2
2
 
3
3
Copyright (C) 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994,
4
4
    1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
5
 
    2006, 2007, 2008, 2009, 2010 Massachusetts Institute of Technology
 
5
    2006, 2007, 2008, 2009, 2010, 2011 Massachusetts Institute of
 
6
    Technology
6
7
 
7
8
This file is part of MIT/GNU Scheme.
8
9
 
32
33
#endif
33
34
 
34
35
#include "bignmint.h"
 
36
#include "bits.h"
35
37
 
36
38
#ifndef MIT_SCHEME
37
39
 
100
102
static bignum_type bignum_new_sign (bignum_type, int);
101
103
static bignum_type bignum_maybe_new_sign (bignum_type, int);
102
104
static void bignum_destructive_copy (bignum_type, bignum_type);
103
 
 
104
 
#define ULONG_LENGTH_IN_BITS(digit, len) do                             \
105
 
{                                                                       \
106
 
  unsigned long w = digit;                                              \
107
 
  len = 0;                                                              \
108
 
  while (w > 0xff) { len += 8; w >>= 8; }                               \
109
 
  while (w > 0)    { len += 1; w >>= 1; }                               \
110
 
} while (0)
111
105
 
112
106
/* Exports */
113
107
 
425
419
    }
426
420
}
427
421
 
428
 
bignum_type
429
 
long_to_bignum (long n)
430
 
{
431
 
  int negative_p;
432
 
  bignum_digit_type result_digits [BIGNUM_DIGITS_FOR_LONG];
433
 
  bignum_digit_type * end_digits = result_digits;
434
 
  /* Special cases win when these small constants are cached. */
435
 
  if (n == 0) return (BIGNUM_ZERO ());
436
 
  if (n == 1) return (BIGNUM_ONE (0));
437
 
  if (n == -1) return (BIGNUM_ONE (1));
438
 
  {
439
 
    unsigned long accumulator = ((negative_p = (n < 0)) ? (-n) : n);
440
 
    do
441
 
      {
442
 
        (*end_digits++) = (accumulator & BIGNUM_DIGIT_MASK);
443
 
        accumulator >>= BIGNUM_DIGIT_LENGTH;
444
 
      }
445
 
    while (accumulator != 0);
446
 
  }
447
 
  {
448
 
    bignum_type result =
449
 
      (bignum_allocate ((end_digits - result_digits), negative_p));
450
 
    bignum_digit_type * scan_digits = result_digits;
451
 
    bignum_digit_type * scan_result = (BIGNUM_START_PTR (result));
452
 
    while (scan_digits < end_digits)
453
 
      (*scan_result++) = (*scan_digits++);
454
 
    return (result);
455
 
  }
456
 
}
457
 
 
458
 
long
459
 
bignum_to_long (bignum_type bignum)
460
 
{
461
 
  if (BIGNUM_ZERO_P (bignum))
462
 
    return (0);
463
 
  {
464
 
    unsigned long accumulator = 0;
465
 
    bignum_digit_type * start = (BIGNUM_START_PTR (bignum));
466
 
    bignum_digit_type * scan = (start + (BIGNUM_LENGTH (bignum)));
467
 
    while (start < scan)
468
 
      accumulator = ((accumulator << BIGNUM_DIGIT_LENGTH) + (*--scan));
469
 
    return
470
 
      ((BIGNUM_NEGATIVE_P (bignum))
471
 
       ? (- ((long) accumulator))
472
 
       : ((long) accumulator));
473
 
  }
474
 
}
475
 
 
476
 
bignum_type
477
 
ulong_to_bignum (unsigned long n)
478
 
{
479
 
  bignum_digit_type result_digits [BIGNUM_DIGITS_FOR_LONG];
480
 
  bignum_digit_type * end_digits = result_digits;
481
 
  /* Special cases win when these small constants are cached. */
482
 
  if (n == 0) return (BIGNUM_ZERO ());
483
 
  if (n == 1) return (BIGNUM_ONE (0));
484
 
  {
485
 
    unsigned long accumulator = n;
486
 
    do
487
 
      {
488
 
        (*end_digits++) = (accumulator & BIGNUM_DIGIT_MASK);
489
 
        accumulator >>= BIGNUM_DIGIT_LENGTH;
490
 
      }
491
 
    while (accumulator != 0);
492
 
  }
493
 
  {
494
 
    bignum_type result =
495
 
      (bignum_allocate ((end_digits - result_digits), 0));
496
 
    bignum_digit_type * scan_digits = result_digits;
497
 
    bignum_digit_type * scan_result = (BIGNUM_START_PTR (result));
498
 
    while (scan_digits < end_digits)
499
 
      (*scan_result++) = (*scan_digits++);
500
 
    return (result);
501
 
  }
502
 
}
503
 
 
504
 
unsigned long
505
 
bignum_to_ulong (bignum_type bignum)
506
 
{
507
 
  if (BIGNUM_ZERO_P (bignum))
508
 
    return (0);
509
 
  BIGNUM_ASSERT (BIGNUM_POSITIVE_P (bignum));
510
 
  {
511
 
    unsigned long accumulator = 0;
512
 
    bignum_digit_type * start = (BIGNUM_START_PTR (bignum));
513
 
    bignum_digit_type * scan = (start + (BIGNUM_LENGTH (bignum)));
514
 
    while (start < scan)
515
 
      accumulator = ((accumulator << BIGNUM_DIGIT_LENGTH) + (*--scan));
516
 
    return (accumulator);
517
 
  }
518
 
}
 
422
static bignum_type
 
423
bignum_from_digits (bignum_digit_type *start_digits,
 
424
                    bignum_digit_type *end_digits,
 
425
                    bool negative_p)
 
426
{
 
427
  bignum_type result =
 
428
    (bignum_allocate ((end_digits - start_digits), negative_p));
 
429
  bignum_digit_type *scan_digits = start_digits;
 
430
  bignum_digit_type *scan_result = (BIGNUM_START_PTR (result));
 
431
  while (scan_digits < end_digits)
 
432
    (*scan_result++) = (*scan_digits++);
 
433
  return (result);
 
434
}
 
435
 
 
436
#define DEFINE_INT_TO_BIGNUM(NAME, TYPE, UTYPE)                         \
 
437
bignum_type                                                             \
 
438
NAME (TYPE n)                                                           \
 
439
{                                                                       \
 
440
  /* Special cases win when these small constants are cached.  */       \
 
441
  if (n == 0) return (BIGNUM_ZERO ());                                  \
 
442
  if (n == 1) return (BIGNUM_ONE (0));                                  \
 
443
  if (n == -1) return (BIGNUM_ONE (1));                                 \
 
444
  {                                                                     \
 
445
    int negative_p;                                                     \
 
446
    bignum_digit_type result_digits [BIGNUM_DIGITS_FOR_TYPE (TYPE)];    \
 
447
    bignum_digit_type * end_digits = result_digits;                     \
 
448
    UTYPE accumulator = ((negative_p = (n < 0)) ? (-n) : n);            \
 
449
    do {                                                                \
 
450
      (*end_digits++) = (accumulator & BIGNUM_DIGIT_MASK);              \
 
451
      accumulator >>= BIGNUM_DIGIT_LENGTH;                              \
 
452
    } while (accumulator != 0);                                         \
 
453
    return                                                              \
 
454
      (bignum_from_digits (result_digits, end_digits, negative_p));     \
 
455
  }                                                                     \
 
456
}
 
457
 
 
458
DEFINE_INT_TO_BIGNUM (long_to_bignum, long, unsigned long)
 
459
DEFINE_INT_TO_BIGNUM (intmax_to_bignum, intmax_t, uintmax_t)
 
460
 
 
461
#define DEFINE_BIGNUM_TO_INT(NAME, TYPE, UTYPE)                         \
 
462
TYPE                                                                    \
 
463
NAME (bignum_type bignum)                                               \
 
464
{                                                                       \
 
465
  if (BIGNUM_ZERO_P (bignum))                                           \
 
466
    return (0);                                                         \
 
467
  {                                                                     \
 
468
    UTYPE accumulator = 0;                                              \
 
469
    bignum_digit_type * start = (BIGNUM_START_PTR (bignum));            \
 
470
    bignum_digit_type * scan = (start + (BIGNUM_LENGTH (bignum)));      \
 
471
    while (start < scan)                                                \
 
472
      accumulator = ((accumulator << BIGNUM_DIGIT_LENGTH) + (*--scan)); \
 
473
    return                                                              \
 
474
      ((BIGNUM_NEGATIVE_P (bignum))                                     \
 
475
       ? (- ((TYPE) accumulator))                                       \
 
476
       : ((TYPE) accumulator));                                         \
 
477
  }                                                                     \
 
478
}
 
479
 
 
480
DEFINE_BIGNUM_TO_INT (bignum_to_long, long, unsigned long)
 
481
DEFINE_BIGNUM_TO_INT (bignum_to_intmax, intmax_t, uintmax_t)
 
482
 
 
483
#define DEFINE_UINT_TO_BIGNUM(NAME, TYPE)                               \
 
484
bignum_type                                                             \
 
485
NAME (TYPE n)                                                           \
 
486
{                                                                       \
 
487
  /* Special cases win when these small constants are cached. */        \
 
488
  if (n == 0) return (BIGNUM_ZERO ());                                  \
 
489
  if (n == 1) return (BIGNUM_ONE (0));                                  \
 
490
  {                                                                     \
 
491
    bignum_digit_type result_digits [BIGNUM_DIGITS_FOR_TYPE (TYPE)];    \
 
492
    bignum_digit_type * end_digits = result_digits;                     \
 
493
    TYPE accumulator = n;                                               \
 
494
    do {                                                                \
 
495
      (*end_digits++) = (accumulator & BIGNUM_DIGIT_MASK);              \
 
496
      accumulator >>= BIGNUM_DIGIT_LENGTH;                              \
 
497
    } while (accumulator != 0);                                         \
 
498
    return (bignum_from_digits (result_digits, end_digits, false));     \
 
499
  }                                                                     \
 
500
}
 
501
 
 
502
DEFINE_UINT_TO_BIGNUM (ulong_to_bignum, unsigned long)
 
503
DEFINE_UINT_TO_BIGNUM (uintmax_to_bignum, uintmax_t)
 
504
 
 
505
#define DEFINE_BIGNUM_TO_UINT(NAME, TYPE)                               \
 
506
TYPE                                                                    \
 
507
NAME (bignum_type bignum)                                               \
 
508
{                                                                       \
 
509
  if (BIGNUM_ZERO_P (bignum))                                           \
 
510
    return (0);                                                         \
 
511
  BIGNUM_ASSERT (BIGNUM_POSITIVE_P (bignum));                           \
 
512
  {                                                                     \
 
513
    TYPE accumulator = 0;                                               \
 
514
    bignum_digit_type * start = (BIGNUM_START_PTR (bignum));            \
 
515
    bignum_digit_type * scan = (start + (BIGNUM_LENGTH (bignum)));      \
 
516
    while (start < scan)                                                \
 
517
      accumulator = ((accumulator << BIGNUM_DIGIT_LENGTH) + (*--scan)); \
 
518
    return (accumulator);                                               \
 
519
  }                                                                     \
 
520
}
 
521
 
 
522
DEFINE_BIGNUM_TO_UINT (bignum_to_ulong, unsigned long)
 
523
DEFINE_BIGNUM_TO_UINT (bignum_to_uintmax, uintmax_t)
519
524
 
520
525
#define DTB_WRITE_DIGIT(n_bits) do                                      \
521
526
{                                                                       \
611
616
#  include "error: must have FLT_RADIX==2"
612
617
#endif
613
618
    double value = 0;
614
 
    bignum_digit_type mask = 0;
615
619
    bignum_digit_type guard_bit_mask = BIGNUM_RADIX>>1;
616
620
    bignum_digit_type rounding_correction = 0;
617
 
    int current_digit_bit_count = 0;
618
 
 
619
 
    ULONG_LENGTH_IN_BITS (msd, current_digit_bit_count);
620
 
    mask = ((1UL << current_digit_bit_count) - 1UL);
 
621
    int current_digit_bit_count = (ulong_length_in_bits (msd));
 
622
    bignum_digit_type mask = (BIGNUM_DIGIT_ONES (current_digit_bit_count));
621
623
 
622
624
    while (1) {
623
625
      if (current_digit_bit_count > bits_to_get) {
770
772
    }
771
773
  }
772
774
}
773
 
 
774
 
bignum_type
 
775
 
 
776
/* All these bitwise operations are complicated because they interpret
 
777
   integers as their two's-complement representations, whereas bignums
 
778
   are stored in a ones-complement representation.  */
 
779
 
 
780
bignum_type
 
781
bignum_bitwise_not (bignum_type bignum)
 
782
{
 
783
  return (bignum_subtract ((BIGNUM_ONE (1)), bignum));
 
784
}
 
785
 
 
786
#define DEFINE_BITWISE_UNSIGNED(NAME, COMMUTE, OP, POSTOP)      \
 
787
static bignum_type                                              \
 
788
NAME (bignum_type x, bignum_type y)                             \
 
789
{                                                               \
 
790
  if ((BIGNUM_LENGTH (x)) < (BIGNUM_LENGTH (y)))                \
 
791
    COMMUTE (y, x);                                             \
 
792
  {                                                             \
 
793
    bignum_length_type x_length = (BIGNUM_LENGTH (x));          \
 
794
    bignum_length_type y_length = (BIGNUM_LENGTH (y));          \
 
795
    bignum_length_type r_length = x_length;                     \
 
796
    bignum_type r = (bignum_allocate (r_length, 0));            \
 
797
    bignum_digit_type *x_scan = (BIGNUM_START_PTR (x));         \
 
798
    bignum_digit_type *x_end = (x_scan + x_length);             \
 
799
    bignum_digit_type *y_scan = (BIGNUM_START_PTR (y));         \
 
800
    bignum_digit_type *y_end = (y_scan + y_length);             \
 
801
    bignum_digit_type *r_scan = (BIGNUM_START_PTR (r));         \
 
802
    BIGNUM_ASSERT (x_length >= y_length);                       \
 
803
    while (y_scan < y_end)                                      \
 
804
      (*r_scan++) = (BITWISE_##OP ((*x_scan++), (*y_scan++)));  \
 
805
    while (x_scan < x_end)                                      \
 
806
      (*r_scan++) = (BITWISE_##OP ((*x_scan++), 0));            \
 
807
    return (POSTOP (bignum_trim (r)));                          \
 
808
  }                                                             \
 
809
}
 
810
 
 
811
#define BITWISE_AND(x, y) ((x) & (y))
 
812
#define BITWISE_ANDC2(x, y) ((x) &~ (y))
 
813
#define BITWISE_ANDC1(x, y) ((y) &~ (x))
 
814
#define BITWISE_XOR(x, y) ((x) ^ (y))
 
815
#define BITWISE_IOR(x, y) ((x) | (y))
 
816
 
 
817
/* These don't work, because they set the high bits.  */
 
818
/* #define BITWISE_ORC2(x, y) (BIGNUM_DIGIT_MASK & ((x) |~ (y))) */
 
819
/* #define BITWISE_ORC1(x, y) (BIGNUM_DIGIT_MASK & ((y) |~ (x))) */
 
820
 
 
821
/* Kludgey syntactic hack!  */
 
822
#define COMMUTE(name) return bignum_bitwise_##name##_unsigned
 
823
#define SWAP(x, y) do { bignum_type t = x; x = y; y = t; } while (0)
 
824
 
 
825
static bignum_type bignum_bitwise_andc1_unsigned (bignum_type, bignum_type);
 
826
static bignum_type bignum_bitwise_orc1_unsigned (bignum_type, bignum_type);
 
827
 
 
828
/* These definitions are ordered by their truth tables.  */
 
829
 
 
830
/* DEFINE_BITWISE_UNSIGNED (bignum_bitwise_clear_unsigned, SWAP, CLEAR,) */
 
831
DEFINE_BITWISE_UNSIGNED (bignum_bitwise_and_unsigned, SWAP, AND,)
 
832
DEFINE_BITWISE_UNSIGNED (bignum_bitwise_andc2_unsigned, COMMUTE(andc1), ANDC2,)
 
833
/* DEFINE_BITWISE_UNSIGNED (bignum_bitwise_arg1_unsigned, COMMUTE(ARG2), ARG1,) */
 
834
DEFINE_BITWISE_UNSIGNED (bignum_bitwise_andc1_unsigned, COMMUTE(andc2), ANDC1,)
 
835
/* DEFINE_BITWISE_UNSIGNED (bignum_bitwise_arg2_unsigned, ARG2,) */
 
836
DEFINE_BITWISE_UNSIGNED (bignum_bitwise_xor_unsigned, SWAP, XOR,)
 
837
DEFINE_BITWISE_UNSIGNED (bignum_bitwise_ior_unsigned, SWAP, IOR,)
 
838
DEFINE_BITWISE_UNSIGNED (bignum_bitwise_nor_unsigned, SWAP, IOR, bignum_bitwise_not)
 
839
DEFINE_BITWISE_UNSIGNED (bignum_bitwise_eqv_unsigned, SWAP, XOR, bignum_bitwise_not)
 
840
/* DEFINE_BITWISE_UNSIGNED (bignum_bitwise_not2_unsigned, COMMUTE(not1), ARG1, bignum_bitwise_not) */
 
841
/* DEFINE_BITWISE_UNSIGNED (bignum_bitwise_orc2_unsigned, COMMUTE(orc1), ORC2,) */
 
842
/* DEFINE_BITWISE_UNSIGNED (bignum_bitwise_not1_unsigned, COMMUTE(not1), ARG2, bignum_bitwise_not) */
 
843
/* DEFINE_BITWISE_UNSIGNED (bignum_bitwise_orc1_unsigned, COMMUTE(orc2), ORC2,) */
 
844
DEFINE_BITWISE_UNSIGNED (bignum_bitwise_nand_unsigned, SWAP, AND, bignum_bitwise_not)
 
845
/* DEFINE_BITWISE_UNSIGNED (bignum_bitwise_set_unsigned, SWAP, CLEAR, bignum_bitwise_not) */
 
846
 
 
847
static bignum_type
 
848
bignum_bitwise_orc2_unsigned (bignum_type x, bignum_type y)
 
849
{
 
850
  return (bignum_bitwise_not (bignum_bitwise_andc1 (x, y)));
 
851
}
 
852
 
 
853
static bignum_type
 
854
bignum_bitwise_orc1_unsigned (bignum_type x, bignum_type y)
 
855
{
 
856
  return (bignum_bitwise_not (bignum_bitwise_andc2 (x, y)));
 
857
}
 
858
 
 
859
#undef SWAP
 
860
#undef COMMUTE
 
861
#undef DEFINE_BITWISE_UNSIGNED
 
862
 
 
863
#define DEFINE_BITWISE(NAME, X0, Y0, PP, PN, NP, NN)                    \
 
864
bignum_type                                                             \
 
865
NAME (bignum_type x, bignum_type y)                                     \
 
866
{                                                                       \
 
867
  if (BIGNUM_ZERO_P (x)) return (Y0);                                   \
 
868
  if (BIGNUM_ZERO_P (y)) return (X0);                                   \
 
869
  return                                                                \
 
870
    ((BIGNUM_POSITIVE_P (x))                                            \
 
871
     ? ((BIGNUM_POSITIVE_P (y))                                         \
 
872
        ? (bignum_bitwise_##PP##_unsigned (x, y))                       \
 
873
        : (bignum_bitwise_##PN##_unsigned (x, (bignum_bitwise_not (y))))) \
 
874
     : ((BIGNUM_POSITIVE_P (y))                                         \
 
875
        ? (bignum_bitwise_##NP##_unsigned ((bignum_bitwise_not (x)), y)) \
 
876
        : (bignum_bitwise_##NN##_unsigned                               \
 
877
           ((bignum_bitwise_not (x)), (bignum_bitwise_not (y)))))); \
 
878
}
 
879
 
 
880
DEFINE_BITWISE (bignum_bitwise_and, (BIGNUM_ZERO ()), (BIGNUM_ZERO ()),
 
881
                and, andc2, andc1, nor)
 
882
 
 
883
DEFINE_BITWISE (bignum_bitwise_andc2, x, (BIGNUM_ZERO ()),
 
884
                andc2, and, nor, andc1)
 
885
 
 
886
DEFINE_BITWISE (bignum_bitwise_andc1, (BIGNUM_ZERO ()), y,
 
887
                andc1, nor, and, andc2)
 
888
 
 
889
DEFINE_BITWISE (bignum_bitwise_xor, x, y, xor, eqv, eqv, xor)
 
890
 
 
891
DEFINE_BITWISE (bignum_bitwise_ior, x, y, ior, orc2, orc1, nand)
 
892
 
 
893
DEFINE_BITWISE (bignum_bitwise_nor,
 
894
                (bignum_bitwise_not (x)),
 
895
                (bignum_bitwise_not (y)),
 
896
                nor, andc1, andc2, and)
 
897
 
 
898
DEFINE_BITWISE (bignum_bitwise_eqv,
 
899
                (bignum_bitwise_not (x)),
 
900
                (bignum_bitwise_not (y)),
 
901
                eqv, xor, xor, eqv)
 
902
 
 
903
DEFINE_BITWISE (bignum_bitwise_orc2,
 
904
                (BIGNUM_ONE (1)), (bignum_bitwise_not (y)),
 
905
                orc2, ior, nand, orc1)
 
906
 
 
907
DEFINE_BITWISE (bignum_bitwise_orc1,
 
908
                (bignum_bitwise_not (x)), (BIGNUM_ONE (1)),
 
909
                orc1, nand, ior, orc2)
 
910
 
 
911
DEFINE_BITWISE (bignum_bitwise_nand, (BIGNUM_ONE (1)), (BIGNUM_ONE (1)),
 
912
                nand, orc1, orc2, ior)
 
913
 
 
914
#undef DEFINE_BITWISE
 
915
 
 
916
/* General bit-twiddlers.  */
 
917
 
 
918
/* (edit a a-pos b b-pos selector size)
 
919
     = (ior (and a (shift-left selector a-pos))
 
920
            (shift-left (and (shift-right b b-pos) (not selector)) a-pos))
 
921
 
 
922
   In other words, replace a[a-pos + i] by b[b-pos + i] if selector[i]
 
923
   is zero, and shift the result right by pos (which can be negative).
 
924
   For example, (extract size pos x) = (edit x pos 0 0 (mask size 0)).  */
 
925
 
 
926
#if 0
 
927
bignum_type
 
928
bignum_edit_bit_field (bignum_type x, unsigned long x_position,
 
929
                       bignum_type y, unsigned long y_position,
 
930
                       bignum_type selector, unsigned long size)
 
931
{
 
932
  BIGNUM_ASSERT (!BIGNUM_NEGATIVE_P (x));
 
933
  BIGNUM_ASSERT (!BIGNUM_NEGATIVE_P (y));
 
934
  BIGNUM_ASSERT (!BIGNUM_NEGATIVE_P (selector));
 
935
  if (BIGNUM_ZERO_P (selector))
 
936
    return (x);
 
937
  {
 
938
    bignum_length_type x_length = (BIGNUM_LENGTH (x));
 
939
    bignum_length_type y_length = (BIGNUM_LENGTH (y));
 
940
    bignum_length_type selector_length = (BIGNUM_LENGTH (selector));
 
941
    bignum_length_type r_length = (MAX (x_length, (y_position + size)));
 
942
    bignum_type r = (bignum_allocate (r_length, (BIGNUM_NEGATIVE_P (x))));
 
943
    bignum_length_type x_digit_position = (x_position / BIGNUM_DIGIT_LENGTH);
 
944
    bignum_length_type y_digit_position = (y_position / BIGNUM_DIGIT_LENGTH);
 
945
    bignum_length_type x_bit_position = (x_position % BIGNUM_DIGIT_LENGTH);
 
946
    bignum_length_type y_bit_position = (y_position % BIGNUM_DIGIT_LENGTH);
 
947
    bignum_digit_type *x_scan = (BIGNUM_START_PTR (x));
 
948
    bignum_digit_type *y_scan = (BIGNUM_START_PTR (y));
 
949
    bignum_digit_type *selector_scan = (BIGNUM_START_PTR (selector));
 
950
    bignum_digit_type *r_scan = (BIGNUM_START_PTR (r));
 
951
    bignum_digit_type *x_end = (x_scan + x_length);
 
952
    bignum_digit_type *y_end = (y_scan + y_length);
 
953
    bignum_digit_type *selector_end = (selector_scan + selector_length);
 
954
    {
 
955
      bignum_digit_type *stop = (x_scan + (MIN (x_digit_position, x_length)));
 
956
      while (x_scan < stop)
 
957
        (*r_scan++) = (*x_scan++);
 
958
    }
 
959
    /* Four cases to deal with, depending on whether or not x and y
 
960
       have more digits.  */
 
961
    y_scan += (MIN (y_digit_position, (y_end - y_scan)));
 
962
    if ((x_scan < x_end) && (y_scan < y_end))
 
963
      {
 
964
        bignum_digit_type x_low_mask = (BIGNUM_DIGIT_ONES (x_bit_position));
 
965
        bignum_digit_type x_high_mask
 
966
          = (BIGNUM_DIGIT_ONES (BIGNUM_DIGIT_LENGTH - x_bit_position));
 
967
        bignum_digit_type y_low_mask = (BIGNUM_DIGIT_ONES (y_bit_position));
 
968
        bignum_digit_type y_high_mask
 
969
          = (BIGNUM_DIGIT_ONES (BIGNUM_DIGIT_LENGTH - y_bit_position));
 
970
        bignum_digit_type r_carry = ((*x_scan) & x_low_mask);
 
971
        bignum_digit_type x_carry
 
972
          = (((*x_scan++) >> x_bit_position) & x_high_mask);
 
973
        bignum_digit_type y_carry
 
974
          = (((*y_scan++) >> y_bit_position) & y_high_mask);
 
975
        while ((x_scan < x_end) && (y_scan < y_end))
 
976
          {
 
977
            bignum_digit_type selector = (*selector_scan++);
 
978
            bignum_digit_type x = (*x_scan++);
 
979
            bignum_digit_type y = (*y_scan++);
 
980
            (*r_scan++)
 
981
              = (r_carry
 
982
                 | ((x_carry ) << x_bit_position)
 
983
 
 
984
 
 
985
                 | ((((x >> x_bit_position) & x_high_mask &~ selector)
 
986
                     | (high_y & selector))
 
987
                    << x_bit_position));
 
988
            carry = ...;
 
989
          }
 
990
      }
 
991
    else if (x_scan < x_end)
 
992
      {
 
993
      }
 
994
    else if (y_scan < y_end)
 
995
      {
 
996
      }
 
997
    else
 
998
      {
 
999
      }
 
1000
  }
 
1001
}
 
1002
#endif /* 0 */
 
1003
 
 
1004
/* (splice a a-pos b b-pos size)
 
1005
     = (edit a a-pos b b-pos (mask size) size)
 
1006
 
 
1007
   Thus, e.g., (extract size pos x) = (splice x pos 0 0 size).  */
 
1008
 
 
1009
#if 0
 
1010
bignum_type
 
1011
bignum_splice_bit_field (bignum_type x, unsigned long x_position,
 
1012
                         bignum_type y, unsigned long y_position,
 
1013
                         unsigned long size)
 
1014
{
 
1015
  ...
 
1016
}
 
1017
#endif /* 0 */
 
1018
 
 
1019
/* Ones-complement length.  */
 
1020
 
 
1021
unsigned long
775
1022
bignum_length_in_bits (bignum_type bignum)
776
1023
{
777
1024
  if (BIGNUM_ZERO_P (bignum))
778
 
    return (BIGNUM_ZERO ());
 
1025
    return (0);
779
1026
  {
780
1027
    bignum_length_type index = ((BIGNUM_LENGTH (bignum)) - 1);
781
 
    bignum_digit_type digit = (BIGNUM_REF (bignum, index));
782
 
    bignum_digit_type delta = 0;
783
 
    bignum_type result = (bignum_allocate (2, 0));
784
 
    (BIGNUM_REF (result, 0)) = index;
785
 
    (BIGNUM_REF (result, 1)) = 0;
786
 
    bignum_destructive_scale_up (result, BIGNUM_DIGIT_LENGTH);
787
 
    ULONG_LENGTH_IN_BITS (digit, delta);
788
 
    bignum_destructive_add (result, ((bignum_digit_type) delta));
789
 
    return (bignum_trim (result));
790
 
  }
791
 
}
792
 
 
793
 
bignum_type
794
 
bignum_length_upper_limit (void)
795
 
{
796
 
  bignum_type result = (bignum_allocate (2, 0));
797
 
  (BIGNUM_REF (result, 0)) = 0;
798
 
  (BIGNUM_REF (result, 1)) = BIGNUM_DIGIT_LENGTH;
799
 
  return (result);
 
1028
    return
 
1029
      ((ulong_length_in_bits (BIGNUM_REF (bignum, index)))
 
1030
       + (BIGNUM_DIGIT_LENGTH * index));
 
1031
  }
 
1032
}
 
1033
 
 
1034
/* Two's-complement length.  */
 
1035
 
 
1036
unsigned long
 
1037
bignum_integer_length (bignum_type bignum)
 
1038
{
 
1039
  unsigned long length_in_bits = (bignum_length_in_bits (bignum));
 
1040
  if ((BIGNUM_ZERO_P (bignum)) || (BIGNUM_POSITIVE_P (bignum)))
 
1041
    return (length_in_bits);
 
1042
  /* else if (BIGNUM_NEGATIVE_P (bignum)) */
 
1043
  {
 
1044
    /* We have to test whether it is a negative power of two.  If so,
 
1045
       we treat its length as one less than bignum_length_in_bits,
 
1046
       because we are really measuring the length of the finite
 
1047
       sequence of bits before the infinite sequence of zero bits (for
 
1048
       nonnegative integers) or one bits (for negative integers) in the
 
1049
       integer's general two's-complement representation.  Thus,
 
1050
       negative powers of two appear to have one fewer bit.  */
 
1051
    bignum_digit_type *scan = (BIGNUM_START_PTR (bignum));
 
1052
    bignum_digit_type *end = (scan + (BIGNUM_LENGTH (bignum)) - 1);
 
1053
    while (scan < end)
 
1054
      if (0 != (*scan++))
 
1055
        return (length_in_bits);
 
1056
    return (length_in_bits - (0 == ((*end) & ((*end) - 1))));
 
1057
  }
 
1058
}
 
1059
 
 
1060
long
 
1061
bignum_first_set_bit (bignum_type bignum)
 
1062
{
 
1063
  if (BIGNUM_ZERO_P (bignum))
 
1064
    return (-1);
 
1065
  {
 
1066
    bignum_digit_type *start = (BIGNUM_START_PTR (bignum));
 
1067
    bignum_digit_type *scan = start;
 
1068
    bignum_digit_type *end = (scan + (BIGNUM_LENGTH (bignum)));
 
1069
    while (scan < end)
 
1070
      {
 
1071
        if ((*scan) != 0) break;
 
1072
        scan += 1;
 
1073
      }
 
1074
    BIGNUM_ASSERT (scan < end);
 
1075
    return
 
1076
      ((ulong_bit_count (((*scan) ^ ((*scan) - 1)) >> 1))
 
1077
       + ((scan - start) * BIGNUM_DIGIT_LENGTH));
 
1078
  }
 
1079
}
 
1080
 
 
1081
static inline unsigned long
 
1082
digits_bit_count (bignum_digit_type **scan_loc, unsigned long count)
 
1083
{
 
1084
  unsigned long bit_count = 0;
 
1085
  bignum_digit_type *end = ((*scan_loc) + count);
 
1086
  while ((*scan_loc) < end)
 
1087
    bit_count += (ulong_bit_count (* ((*scan_loc) ++)));
 
1088
  return (bit_count);
 
1089
}
 
1090
 
 
1091
static inline unsigned long
 
1092
digits_hamming_distance (bignum_digit_type **x_scan_loc,
 
1093
                         bignum_digit_type **y_scan_loc,
 
1094
                         unsigned long count)
 
1095
{
 
1096
  unsigned long hamming_distance = 0;
 
1097
  bignum_digit_type *end = ((*x_scan_loc) + count);
 
1098
  while ((*x_scan_loc) < end)
 
1099
    hamming_distance
 
1100
      += (ulong_bit_count ((* ((*x_scan_loc) ++)) ^ (* ((*y_scan_loc) ++))));
 
1101
  return (hamming_distance);
 
1102
}
 
1103
 
 
1104
/* Hamming distance: the easy case.  */
 
1105
 
 
1106
static unsigned long
 
1107
bignum_positive_hamming_distance (bignum_type x, bignum_type y)
 
1108
{
 
1109
  BIGNUM_ASSERT (!BIGNUM_ZERO_P (x));
 
1110
  BIGNUM_ASSERT (!BIGNUM_ZERO_P (y));
 
1111
  BIGNUM_ASSERT (BIGNUM_POSITIVE_P (x));
 
1112
  BIGNUM_ASSERT (BIGNUM_POSITIVE_P (y));
 
1113
  if ((BIGNUM_LENGTH (x)) < (BIGNUM_LENGTH (y)))
 
1114
    {
 
1115
      bignum_type t = x; x = y; y = t;
 
1116
    }
 
1117
  {
 
1118
    bignum_digit_type *x_scan = (BIGNUM_START_PTR (x));
 
1119
    bignum_digit_type *y_scan = (BIGNUM_START_PTR (y));
 
1120
    unsigned long hamming_distance
 
1121
      = (digits_hamming_distance
 
1122
         ((&x_scan), (&y_scan), (BIGNUM_LENGTH (y))));
 
1123
    hamming_distance
 
1124
      += (digits_bit_count
 
1125
          ((&x_scan), ((BIGNUM_LENGTH (x)) - (BIGNUM_LENGTH (y)))));
 
1126
    return (hamming_distance);
 
1127
  }
 
1128
}
 
1129
 
 
1130
/* Hamming distance: the hard case.  */
 
1131
 
 
1132
#if 0
 
1133
/* Is this actually faster than (hamming-distance (not x) (not y))?  */
 
1134
 
 
1135
#define MIN(A,B) (((A) < (B)) ? (A) : (B))
 
1136
 
 
1137
static unsigned long
 
1138
bignum_negative_hamming_distance (bignum_type x, bignum_type y)
 
1139
{
 
1140
  BIGNUM_ASSERT (!BIGNUM_ZERO_P (x));
 
1141
  BIGNUM_ASSERT (!BIGNUM_ZERO_P (y));
 
1142
  BIGNUM_ASSERT (BIGNUM_NEGATIVE_P (x));
 
1143
  BIGNUM_ASSERT (BIGNUM_NEGATIVE_P (y));
 
1144
  {
 
1145
    bignum_digit_type *x_scan = (BIGNUM_START_PTR (x));
 
1146
    bignum_digit_type *y_scan = (BIGNUM_START_PTR (y));
 
1147
    bignum_digit_type *x_end = (x_scan + (BIGNUM_LENGTH (x)));
 
1148
    bignum_digit_type *y_end = (y_scan + (BIGNUM_LENGTH (y)));
 
1149
    bignum_digit_type x_digit, y_digit;
 
1150
    unsigned long hamming_distance;
 
1151
    /* Find the position of the first nonzero digit of x or y, and
 
1152
       maybe exchange x and y to guarantee that x's is nonzero.  */
 
1153
    while (1)
 
1154
      {
 
1155
        BIGNUM_ASSERT (x_scan < x_end);
 
1156
        BIGNUM_ASSERT (y_scan < y_end);
 
1157
        x_digit = (*x_scan++);
 
1158
        y_digit = (*y_scan++);
 
1159
        if (x_digit != 0) break;
 
1160
        if (y_digit != 0)
 
1161
          {
 
1162
            bignum_digit_type *t;
 
1163
            t = x_scan; x_scan = y_scan; y_scan = t;
 
1164
            t = x_end; x_end = y_end; y_end = t;
 
1165
            x_digit = y_digit;
 
1166
            y_digit = 0;
 
1167
            break;
 
1168
          }
 
1169
      }
 
1170
    /* Convert the first nonzero digit of x and the corresponding digit
 
1171
       (possibly zero) of y to two's-complement.  */
 
1172
    x_digit = (-x_digit);
 
1173
    y_digit = (-y_digit);
 
1174
    hamming_distance
 
1175
      = (ulong_bit_count ((x_digit ^ y_digit) & BIGNUM_DIGIT_MASK));
 
1176
    /* Skip over zeroes in y.  */
 
1177
    if (y_digit == 0)
 
1178
      {
 
1179
        bignum_digit_type *y_ptr = y_scan;
 
1180
        bignum_length_type zeroes;
 
1181
        do {
 
1182
          BIGNUM_ASSERT (y_scan < y_end);
 
1183
          y_digit = (*y_scan++);
 
1184
        } while (y_digit == 0);
 
1185
        /* If we any more zeroes, compute the Hamming distance of that
 
1186
           segment as if all corresponding digits of x were ones.  */
 
1187
        zeroes = (y_scan - y_ptr - 1);
 
1188
        hamming_distance += (zeroes * BIGNUM_DIGIT_LENGTH);
 
1189
        /* Then subtract the amount by which this overestimated.  */
 
1190
        hamming_distance
 
1191
          -= (digits_bit_count ((&x_scan), (MIN ((x_end - x_scan), zeroes))));
 
1192
        /* Convert the first nonzero digit of y to two's-complement --
 
1193
           we can subtract 1 because it is nonzero and (semantically,
 
1194
           if not in the type system) unsigned, and hence positive.  */
 
1195
        hamming_distance
 
1196
          += (ulong_bit_count
 
1197
              ((y_digit - 1) ^ ((x_scan < x_end) ? (*x_scan++) : 0)));
 
1198
      }
 
1199
    /* Finally, scan over the overlapping parts of x and y and then the
 
1200
       non-overlapping high part of whichever is longer.  */
 
1201
    hamming_distance
 
1202
      += (digits_hamming_distance
 
1203
          ((&x_scan), (&y_scan), (MIN ((x_end - x_scan), (y_end - y_scan)))));
 
1204
    hamming_distance
 
1205
      += ((x_scan < x_end)
 
1206
          ? (digits_bit_count ((&x_scan), (x_end - x_scan)))
 
1207
          : (digits_bit_count ((&y_scan), (y_end - y_scan))));
 
1208
    return (hamming_distance);
 
1209
  }
 
1210
}
 
1211
#endif /* 0 */
 
1212
 
 
1213
static unsigned long
 
1214
bignum_bit_count_unsigned (bignum_type x)
 
1215
{
 
1216
  bignum_digit_type *scan = (BIGNUM_START_PTR (x));
 
1217
  return (digits_bit_count ((&scan), (BIGNUM_LENGTH (x))));
 
1218
}
 
1219
 
 
1220
static unsigned long
 
1221
bignum_negative_hamming_distance (bignum_type x, bignum_type y)
 
1222
{
 
1223
  x = (bignum_bitwise_not (x));
 
1224
  y = (bignum_bitwise_not (y));
 
1225
  if (BIGNUM_ZERO_P (x)) return (bignum_bit_count_unsigned (y));
 
1226
  if (BIGNUM_ZERO_P (y)) return (bignum_bit_count_unsigned (x));
 
1227
  return (bignum_positive_hamming_distance (x, y));
 
1228
}
 
1229
 
 
1230
unsigned long
 
1231
bignum_bit_count (bignum_type x) /* a.k.a. Hamming weight, pop count */
 
1232
{
 
1233
  if (BIGNUM_ZERO_P (x))
 
1234
    return (0);
 
1235
  if (BIGNUM_NEGATIVE_P (x))
 
1236
    /* return (bignum_negative_hamming_distance (x, (BIGNUM_ONE (1)))); */
 
1237
    return (bignum_bit_count_unsigned (bignum_bitwise_not (x)));
 
1238
  else
 
1239
    return (bignum_bit_count_unsigned (x));
 
1240
}
 
1241
 
 
1242
long
 
1243
bignum_hamming_distance (bignum_type x, bignum_type y)
 
1244
{
 
1245
  if (x == y)
 
1246
    return (0);
 
1247
  if (BIGNUM_ZERO_P (x))
 
1248
    return ((BIGNUM_NEGATIVE_P (y)) ? (-1) : (bignum_bit_count_unsigned (y)));
 
1249
  if (BIGNUM_ZERO_P (y))
 
1250
    return ((BIGNUM_NEGATIVE_P (x)) ? (-1) : (bignum_bit_count_unsigned (x)));
 
1251
  return
 
1252
    ((BIGNUM_POSITIVE_P (x))
 
1253
     ? ((BIGNUM_POSITIVE_P (y))
 
1254
        ? (bignum_positive_hamming_distance (x, y))
 
1255
        : (-1))
 
1256
     : ((BIGNUM_POSITIVE_P (y))
 
1257
        ? (-1)
 
1258
        : (bignum_negative_hamming_distance (x, y))));
 
1259
}
 
1260
 
 
1261
#if 0
 
1262
 
 
1263
bignum_type
 
1264
bignum_nonnegative_one_bits (unsigned long size, unsigned long position)
 
1265
{
 
1266
  if (size == 0)
 
1267
    return (BIGNUM_ZERO ());
 
1268
  {
 
1269
    unsigned long total = (size + position);
 
1270
    bignum_length_type total_digits = (total / BIGNUM_DIGIT_LENGTH);
 
1271
    bignum_length_type total_bits = (total % BIGNUM_DIGIT_LENGTH);
 
1272
    bignum_length_type zero_digits = (position / BIGNUM_DIGIT_LENGTH);
 
1273
    bignum_length_type zero_bits = (position % BIGNUM_DIGIT_LENGTH);
 
1274
    bignum_length_type one_digits = (size / BIGNUM_DIGIT_LENGTH);
 
1275
    bignum_length_type one_bits = (size % BIGNUM_DIGIT_LENGTH);
 
1276
    bignum_length_type first_nonzero_bits
 
1277
      = (BIGNUM_DIGIT_LENGTH - zero_bits);
 
1278
    bignum_length_type first_one_bits
 
1279
      = ((one_bits < first_nonzero_bits) ? one_bits
 
1280
         : (one_bits - first_nonzero_bits));
 
1281
    bignum_length_type last_one_bits = (one_bits - first_one_bits);
 
1282
    bignum_length_type length = (total_digits + (0 != total_bits));
 
1283
    bignum_type r = (bignum_allocate (length, 0));
 
1284
    bignum_digit_type *r_scan = (BIGNUM_START_PTR (r));
 
1285
    bignum_digit_type *r_zero_end = (r_scan + zero_digits);
 
1286
    bignum_digit_type *r_one_end
 
1287
      = (r_zero_end + (first_one_bits != 0) + one_digits);
 
1288
    BIGNUM_ASSERT ((r_one_end + (last_one_bits != 0)) == (r_scan + length));
 
1289
    while (r_scan < r_zero_end)
 
1290
      (*r_scan++) = 0;
 
1291
    if (first_one_bits != 0)
 
1292
      (*r_scan++) = ((BIGNUM_DIGIT_ONES (first_one_bits)) << zero_bits);
 
1293
    while (r_scan < r_one_end)
 
1294
      (*r_scan++) = BIGNUM_DIGIT_MASK;
 
1295
    if (last_one_bits != 0)
 
1296
      (*r_scan++) = (BIGNUM_DIGIT_ONES (last_one_bits));
 
1297
    return (r);
 
1298
  }
 
1299
}
 
1300
 
 
1301
#endif
 
1302
 
 
1303
bignum_type
 
1304
bignum_nonnegative_one_bits (unsigned long size, unsigned long position)
 
1305
{
 
1306
  return
 
1307
    (bignum_shift_left
 
1308
     ((bignum_bitwise_not (bignum_shift_left ((BIGNUM_ONE (1)), size))),
 
1309
      position));
 
1310
}
 
1311
 
 
1312
bignum_type
 
1313
bignum_negative_zero_bits (unsigned long n, unsigned long m)
 
1314
{
 
1315
  return (bignum_bitwise_not (bignum_nonnegative_one_bits (n, m)));
 
1316
}
 
1317
 
 
1318
static bignum_type
 
1319
bignum_shift_right_unsigned (bignum_type n,
 
1320
                             unsigned long digits,
 
1321
                             unsigned long bits)
 
1322
{
 
1323
  bignum_length_type n_length = (BIGNUM_LENGTH (n));
 
1324
  bignum_digit_type *n_start = (BIGNUM_START_PTR (n));
 
1325
  bignum_digit_type *n_scan = (n_start + digits);
 
1326
  bignum_digit_type *n_end = (n_start + n_length);
 
1327
  bignum_length_type r_length
 
1328
    = (n_length - digits
 
1329
       - ((n_start < n_end) && (0 == ((n_end[-1]) >> bits))));
 
1330
  bignum_type r = (bignum_allocate (r_length, 0));
 
1331
  bignum_digit_type *r_scan = (BIGNUM_START_PTR (r));
 
1332
  if (bits == 0)
 
1333
    while (n_scan < n_end)
 
1334
      (*r_scan++) = (*n_scan++);
 
1335
  else
 
1336
    {
 
1337
      bignum_digit_type mask = (BIGNUM_DIGIT_ONES (bits));
 
1338
      bignum_digit_type shift = (BIGNUM_DIGIT_LENGTH - bits);
 
1339
      bignum_digit_type extra = ((*n_scan++) >> bits);
 
1340
      while (n_scan < n_end)
 
1341
        {
 
1342
          bignum_digit_type digit = (*n_scan++);
 
1343
          (*r_scan++) = (((digit & mask) << shift) | extra);
 
1344
          extra = (digit >> bits);
 
1345
        }
 
1346
      if (extra != 0)
 
1347
        (*r_scan++) = extra;
 
1348
      BIGNUM_ASSERT (r_scan == ((BIGNUM_START_PTR (r)) + r_length));
 
1349
    }
 
1350
  return (r);
 
1351
}
 
1352
 
 
1353
bignum_type
 
1354
bignum_shift_right (bignum_type n, unsigned long m)
 
1355
{
 
1356
  unsigned long digits = (m / BIGNUM_DIGIT_LENGTH);
 
1357
  unsigned long bits = (m % BIGNUM_DIGIT_LENGTH);
 
1358
 
 
1359
  if (digits >= (BIGNUM_LENGTH (n)))
 
1360
    return ((BIGNUM_NEGATIVE_P (n)) ? (BIGNUM_ONE (1)) : (BIGNUM_ZERO ()));
 
1361
 
 
1362
  if (BIGNUM_NEGATIVE_P (n))
 
1363
    return
 
1364
      (bignum_bitwise_not
 
1365
       (bignum_shift_right_unsigned ((bignum_bitwise_not (n)), digits, bits)));
 
1366
  else
 
1367
    return (bignum_shift_right_unsigned (n, digits, bits));
800
1368
}
801
1369
 
802
1370
bignum_type
804
1372
{
805
1373
  unsigned long ln = (BIGNUM_LENGTH (n));
806
1374
  unsigned long delta = 0;
807
 
  if (m == 0)
 
1375
  if ((m == 0) || (BIGNUM_ZERO_P (n)))
808
1376
    return (n);
809
1377
 
810
 
  ULONG_LENGTH_IN_BITS ((BIGNUM_REF (n, (ln - 1))), delta);
 
1378
  delta = (ulong_length_in_bits (BIGNUM_REF (n, (ln - 1))));
811
1379
 
812
1380
  {
813
1381
    unsigned long zeroes = (m / BIGNUM_DIGIT_LENGTH);
847
1415
  if (n == 0)
848
1416
    return (BIGNUM_ZERO ());
849
1417
 
850
 
  ULONG_LENGTH_IN_BITS (n, delta);
 
1418
  delta = (ulong_length_in_bits (n));
851
1419
 
852
1420
  {
853
1421
    unsigned long zeroes = (m / BIGNUM_DIGIT_LENGTH);
886
1454
      return (long_to_bignum (negative_p ? (- digit) : digit));
887
1455
    }
888
1456
  {
889
 
    bignum_length_type length;
890
 
    {
891
 
      unsigned int log_radix = 0;
892
 
      ULONG_LENGTH_IN_BITS (radix, log_radix);
893
 
      /* This length will be at least as large as needed. */
894
 
      length = (BIGNUM_BITS_TO_DIGITS (n_digits * log_radix));
895
 
    }
 
1457
    /* This length will be at least as large as needed. */
 
1458
    bignum_length_type length
 
1459
      = (BIGNUM_BITS_TO_DIGITS
 
1460
         (n_digits * (ulong_length_in_bits (radix))));
896
1461
    {
897
1462
      bignum_type result = (bignum_allocate_zeroed (length, negative_p));
898
1463
      while ((n_digits--) > 0)
1786
2351
static bignum_type
1787
2352
bignum_allocate (bignum_length_type length, int negative_p)
1788
2353
{
1789
 
  BIGNUM_ASSERT ((length >= 0) || (length < BIGNUM_RADIX));
 
2354
  BIGNUM_ASSERT ((0 <= length) && (length <= BIGNUM_LENGTH_MAX));
1790
2355
  {
1791
2356
    bignum_type result = (BIGNUM_ALLOCATE (length));
1792
2357
    BIGNUM_SET_HEADER (result, length, negative_p);
1797
2362
static bignum_type
1798
2363
bignum_allocate_zeroed (bignum_length_type length, int negative_p)
1799
2364
{
1800
 
  BIGNUM_ASSERT ((length >= 0) || (length < BIGNUM_RADIX));
 
2365
  BIGNUM_ASSERT ((0 <= length) && (length <= BIGNUM_LENGTH_MAX));
1801
2366
  {
1802
2367
    bignum_type result = (BIGNUM_ALLOCATE (length));
1803
2368
    bignum_digit_type * scan = (BIGNUM_START_PTR (result));
1813
2378
bignum_shorten_length (bignum_type bignum, bignum_length_type length)
1814
2379
{
1815
2380
  bignum_length_type current_length = (BIGNUM_LENGTH (bignum));
1816
 
  BIGNUM_ASSERT ((length >= 0) || (length <= current_length));
 
2381
  BIGNUM_ASSERT ((0 <= length) && (length <= current_length));
1817
2382
  if (length < current_length)
1818
2383
    {
1819
2384
      BIGNUM_SET_HEADER