File indexing completed on 2026-05-19 08:08:31
0001
0002
0003 #ifndef _CL_INTEGER_H
0004 #define _CL_INTEGER_H
0005
0006 #include "cln/number.h"
0007 #include "cln/integer_class.h"
0008 #include "cln/exception.h"
0009 #include "cln/random.h"
0010
0011 namespace cln {
0012
0013 CL_DEFINE_AS_CONVERSION(cl_I)
0014
0015
0016
0017
0018
0019
0020
0021 extern uint32 cl_I_to_UL (const cl_I& obj);
0022
0023
0024
0025
0026
0027
0028 extern sint32 cl_I_to_L (const cl_I& obj);
0029
0030
0031 #if (int_bitsize==32)
0032 inline int cl_I_to_int (const cl_I& x) { return cl_I_to_L(x); }
0033 inline unsigned int cl_I_to_uint (const cl_I& x) { return cl_I_to_UL(x); }
0034 #endif
0035
0036
0037 #ifdef intQsize
0038 extern uint64 cl_I_to_UQ (const cl_I& obj);
0039 extern sint64 cl_I_to_Q (const cl_I& obj);
0040 #endif
0041
0042
0043 #if (long_bitsize==32)
0044 inline long cl_I_to_long (const cl_I& x) { return cl_I_to_L(x); }
0045 inline unsigned long cl_I_to_ulong (const cl_I& x) { return cl_I_to_UL(x); }
0046 #elif (long_bitsize==64)
0047 inline long cl_I_to_long (const cl_I& x) { return cl_I_to_Q(x); }
0048 inline unsigned long cl_I_to_ulong (const cl_I& x) { return cl_I_to_UQ(x); }
0049 #endif
0050
0051
0052 #if (intCsize==long_bitsize)
0053 inline uintC cl_I_to_UC (const cl_I& x) { return cl_I_to_ulong(x); }
0054 inline sintC cl_I_to_C (const cl_I& x) { return cl_I_to_long(x); }
0055 #elif (intCsize==int_bitsize)
0056 inline uintC cl_I_to_UC (const cl_I& x) { return cl_I_to_uint(x); }
0057 inline sintC cl_I_to_C (const cl_I& x) { return cl_I_to_int(x); }
0058 #endif
0059
0060
0061 #if (intEsize==intLsize)
0062 inline uintE cl_I_to_UE (const cl_I& x) { return cl_I_to_UL(x); }
0063 inline sintE cl_I_to_E (const cl_I& x) { return cl_I_to_L(x); }
0064 #elif (intEsize==intQsize)
0065 inline uintE cl_I_to_UE (const cl_I& x) { return cl_I_to_UQ(x); }
0066 inline sintE cl_I_to_E (const cl_I& x) { return cl_I_to_Q(x); }
0067 #endif
0068
0069
0070
0071
0072
0073
0074 extern const cl_I logior (const cl_I& x, const cl_I& y);
0075
0076
0077
0078 extern const cl_I logxor (const cl_I& x, const cl_I& y);
0079
0080
0081
0082 extern const cl_I logand (const cl_I& x, const cl_I& y);
0083
0084
0085
0086 extern const cl_I logeqv (const cl_I& x, const cl_I& y);
0087
0088
0089
0090 extern const cl_I lognand (const cl_I& x, const cl_I& y);
0091
0092
0093
0094 extern const cl_I lognor (const cl_I& x, const cl_I& y);
0095
0096
0097
0098 extern const cl_I logandc2 (const cl_I& x, const cl_I& y);
0099
0100
0101
0102 inline const cl_I logandc1 (const cl_I& x, const cl_I& y)
0103 {
0104 return logandc2(y,x);
0105 }
0106
0107
0108
0109 extern const cl_I logorc2 (const cl_I& x, const cl_I& y);
0110
0111
0112
0113 inline const cl_I logorc1 (const cl_I& x, const cl_I& y)
0114 {
0115 return logorc2(y,x);
0116 }
0117
0118
0119
0120 extern const cl_I lognot (const cl_I& x);
0121
0122
0123 typedef enum {
0124 boole_clr,
0125 boole_set,
0126 boole_1,
0127 boole_2,
0128 boole_c1,
0129 boole_c2,
0130 boole_and,
0131 boole_ior,
0132 boole_xor,
0133 boole_eqv,
0134 boole_nand,
0135 boole_nor,
0136 boole_andc1,
0137 boole_andc2,
0138 boole_orc1,
0139 boole_orc2
0140 } cl_boole;
0141
0142
0143
0144 extern const cl_I boole (cl_boole op, const cl_I& x, const cl_I& y);
0145
0146
0147
0148
0149 extern bool logtest (const cl_I& x, const cl_I& y);
0150
0151
0152
0153 extern bool logbitp (uintC x, const cl_I& y);
0154 extern bool logbitp (const cl_I& x, const cl_I& y);
0155
0156
0157
0158 extern bool oddp (const cl_I& x);
0159
0160
0161
0162 inline bool evenp (const cl_I& x)
0163 { return !oddp(x); }
0164
0165
0166 extern const cl_I ash (const cl_I& x, sintC y);
0167 extern const cl_I ash (const cl_I& x, const cl_I& y);
0168
0169
0170 class ash_exception : public runtime_exception {
0171 public:
0172 explicit ash_exception (const cl_I& badamount);
0173 };
0174
0175
0176 extern uintC logcount (const cl_I& x);
0177
0178
0179 extern uintC integer_length (const cl_I& x);
0180
0181
0182 extern uintC ord2 (const cl_I& x);
0183
0184
0185
0186 extern uintC power2p (const cl_I& x);
0187
0188 inline const cl_I operator| (const cl_I& x, const cl_I& y)
0189 { return logior(x,y); }
0190 inline const cl_I operator^ (const cl_I& x, const cl_I& y)
0191 { return logxor(x,y); }
0192 inline const cl_I operator& (const cl_I& x, const cl_I& y)
0193 { return logand(x,y); }
0194 inline const cl_I operator~ (const cl_I& x)
0195 { return lognot(x); }
0196
0197 inline cl_I& operator|= (cl_I& x, const cl_I& y) { return x = x | y; }
0198 inline cl_I& operator^= (cl_I& x, const cl_I& y) { return x = x ^ y; }
0199 inline cl_I& operator&= (cl_I& x, const cl_I& y) { return x = x & y; }
0200
0201
0202
0203
0204
0205 extern const cl_I plus1 (const cl_I& x);
0206
0207
0208 extern const cl_I minus1 (const cl_I& x);
0209
0210
0211 extern const cl_I operator+ (const cl_I& x, const cl_I& y);
0212
0213 inline const cl_I operator+ (const int x, const cl_I& y)
0214 { return cl_I(x) + y; }
0215 inline const cl_I operator+ (const unsigned int x, const cl_I& y)
0216 { return cl_I(x) + y; }
0217 inline const cl_I operator+ (const long x, const cl_I& y)
0218 { return cl_I(x) + y; }
0219 inline const cl_I operator+ (const unsigned long x, const cl_I& y)
0220 { return cl_I(x) + y; }
0221 inline const cl_I operator+ (const long long x, const cl_I& y)
0222 { return cl_I(x) + y; }
0223 inline const cl_I operator+ (const unsigned long long x, const cl_I& y)
0224 { return cl_I(x) + y; }
0225 inline const cl_I operator+ (const cl_I& x, const int y)
0226 { return x + cl_I(y); }
0227 inline const cl_I operator+ (const cl_I& x, const unsigned int y)
0228 { return x + cl_I(y); }
0229 inline const cl_I operator+ (const cl_I& x, const long y)
0230 { return x + cl_I(y); }
0231 inline const cl_I operator+ (const cl_I& x, const unsigned long y)
0232 { return x + cl_I(y); }
0233 inline const cl_I operator+ (const cl_I& x, const long long y)
0234 { return x + cl_I(y); }
0235 inline const cl_I operator+ (const cl_I& x, const unsigned long long y)
0236 { return x + cl_I(y); }
0237
0238
0239 extern const cl_I operator- (const cl_I& x);
0240
0241
0242 extern const cl_I operator- (const cl_I& x, const cl_I& y);
0243
0244 inline const cl_I operator- (const int x, const cl_I& y)
0245 { return cl_I(x) - y; }
0246 inline const cl_I operator- (const unsigned int x, const cl_I& y)
0247 { return cl_I(x) - y; }
0248 inline const cl_I operator- (const long x, const cl_I& y)
0249 { return cl_I(x) - y; }
0250 inline const cl_I operator- (const unsigned long x, const cl_I& y)
0251 { return cl_I(x) - y; }
0252 inline const cl_I operator- (const long long x, const cl_I& y)
0253 { return cl_I(x) - y; }
0254 inline const cl_I operator- (const unsigned long long x, const cl_I& y)
0255 { return cl_I(x) - y; }
0256 inline const cl_I operator- (const cl_I& x, const int y)
0257 { return x - cl_I(y); }
0258 inline const cl_I operator- (const cl_I& x, const unsigned int y)
0259 { return x - cl_I(y); }
0260 inline const cl_I operator- (const cl_I& x, const long y)
0261 { return x - cl_I(y); }
0262 inline const cl_I operator- (const cl_I& x, const unsigned long y)
0263 { return x - cl_I(y); }
0264 inline const cl_I operator- (const cl_I& x, const long long y)
0265 { return x - cl_I(y); }
0266 inline const cl_I operator- (const cl_I& x, const unsigned long long y)
0267 { return x - cl_I(y); }
0268
0269
0270 extern const cl_I abs (const cl_I& x);
0271
0272
0273 inline const cl_I operator<< (const cl_I& x, sintC y)
0274 { return ash(x,y); }
0275 inline const cl_I operator<< (const cl_I& x, const cl_I& y)
0276 { return ash(x,y); }
0277 inline const cl_I operator>> (const cl_I& x, sintC y)
0278 { return ash(x,-y); }
0279 inline const cl_I operator>> (const cl_I& x, const cl_I& y)
0280 { return ash(x,-y); }
0281
0282
0283
0284
0285
0286 extern bool equal (const cl_I& x, const cl_I& y);
0287
0288 extern uint32 equal_hashcode (const cl_I& x);
0289
0290
0291
0292 extern cl_signean compare (const cl_I& x, const cl_I& y);
0293
0294 inline bool operator== (const cl_I& x, const cl_I& y)
0295 { return equal(x,y); }
0296 inline bool operator!= (const cl_I& x, const cl_I& y)
0297 { return !equal(x,y); }
0298 inline bool operator<= (const cl_I& x, const cl_I& y)
0299 { return compare(x,y)<=0; }
0300 inline bool operator< (const cl_I& x, const cl_I& y)
0301 { return compare(x,y)<0; }
0302 inline bool operator>= (const cl_I& x, const cl_I& y)
0303 { return compare(x,y)>=0; }
0304 inline bool operator> (const cl_I& x, const cl_I& y)
0305 { return compare(x,y)>0; }
0306
0307
0308 extern bool minusp (const cl_I& x);
0309
0310
0311 extern bool plusp (const cl_I& x);
0312
0313
0314 extern bool zerop (const cl_I& x);
0315
0316
0317
0318
0319 struct cl_byte {
0320 uintC size;
0321 uintC position;
0322
0323 cl_byte (uintC s, uintC p) : size (s), position (p) {}
0324 };
0325
0326
0327 extern const cl_I ldb (const cl_I& n, const cl_byte& b);
0328
0329
0330
0331 extern bool ldb_test (const cl_I& n, const cl_byte& b);
0332
0333
0334 extern const cl_I mask_field (const cl_I& n, const cl_byte& b);
0335
0336
0337 extern const cl_I deposit_field (const cl_I& newbyte, const cl_I& n, const cl_byte& b);
0338
0339
0340 extern const cl_I dpb (const cl_I& newbyte, const cl_I& n, const cl_byte& b);
0341
0342
0343
0344
0345
0346 extern const cl_I operator* (const cl_I& x, const cl_I& y);
0347
0348 inline const cl_I operator* (const int x, const cl_I& y)
0349 { return cl_I(x) * y; }
0350 inline const cl_I operator* (const unsigned int x, const cl_I& y)
0351 { return cl_I(x) * y; }
0352 inline const cl_I operator* (const long x, const cl_I& y)
0353 { return cl_I(x) * y; }
0354 inline const cl_I operator* (const unsigned long x, const cl_I& y)
0355 { return cl_I(x) * y; }
0356 inline const cl_I operator* (const long long x, const cl_I& y)
0357 { return cl_I(x) * y; }
0358 inline const cl_I operator* (const unsigned long long x, const cl_I& y)
0359 { return cl_I(x) * y; }
0360 inline const cl_I operator* (const cl_I& x, const int y)
0361 { return x * cl_I(y); }
0362 inline const cl_I operator* (const cl_I& x, const unsigned int y)
0363 { return x * cl_I(y); }
0364 inline const cl_I operator* (const cl_I& x, const long y)
0365 { return x * cl_I(y); }
0366 inline const cl_I operator* (const cl_I& x, const unsigned long y)
0367 { return x * cl_I(y); }
0368 inline const cl_I operator* (const cl_I& x, const long long y)
0369 { return x * cl_I(y); }
0370 inline const cl_I operator* (const cl_I& x, const unsigned long long y)
0371 { return x * cl_I(y); }
0372
0373
0374 extern const cl_I square (const cl_I& x);
0375
0376
0377 extern const cl_I expt_pos (const cl_I& x, uintL y);
0378 extern const cl_I expt_pos (const cl_I& x, const cl_I& y);
0379
0380
0381 extern const cl_I factorial (uintL n);
0382
0383
0384 extern const cl_I doublefactorial (uintL n);
0385
0386
0387 extern const cl_I binomial (uintL n, uintL k);
0388
0389
0390
0391
0392
0393
0394 struct cl_I_div_t {
0395 cl_I quotient;
0396 cl_I remainder;
0397
0398 cl_I_div_t () {}
0399 cl_I_div_t (const cl_I& q, const cl_I& r) : quotient(q), remainder(r) {}
0400 };
0401
0402
0403
0404
0405
0406
0407 extern const cl_I exquopos (const cl_I& x, const cl_I& y);
0408
0409
0410
0411
0412
0413
0414 extern const cl_I exquo (const cl_I& x, const cl_I& y);
0415
0416
0417 class exquo_exception : public runtime_exception {
0418 public:
0419 exquo_exception (const cl_I& x, const cl_I& y);
0420 };
0421
0422
0423 extern const cl_I mod (const cl_I& x, const cl_I& y);
0424
0425
0426 extern const cl_I rem (const cl_I& x, const cl_I& y);
0427
0428
0429
0430
0431
0432
0433 extern const cl_I_div_t floor2 (const cl_I& x, const cl_I& y);
0434 extern const cl_I floor1 (const cl_I& x, const cl_I& y);
0435
0436
0437
0438
0439
0440
0441 extern const cl_I_div_t ceiling2 (const cl_I& x, const cl_I& y);
0442 extern const cl_I ceiling1 (const cl_I& x, const cl_I& y);
0443
0444
0445
0446
0447
0448
0449 extern const cl_I_div_t truncate2 (const cl_I& x, const cl_I& y);
0450 extern const cl_I truncate1 (const cl_I& x, const cl_I& y);
0451
0452
0453
0454
0455
0456
0457 extern const cl_I_div_t round2 (const cl_I& x, const cl_I& y);
0458 extern const cl_I round1 (const cl_I& x, const cl_I& y);
0459
0460
0461
0462
0463
0464
0465
0466
0467 extern const cl_I gcd (const cl_I& a, const cl_I& b);
0468 extern uintV gcd (uintV a, uintV b);
0469
0470
0471
0472
0473
0474 extern const cl_I xgcd (const cl_I& a, const cl_I& b, cl_I* u, cl_I* v);
0475
0476
0477
0478
0479
0480
0481
0482
0483
0484
0485
0486
0487
0488
0489
0490
0491
0492
0493
0494
0495
0496
0497
0498
0499
0500
0501
0502
0503
0504
0505
0506
0507
0508 extern const cl_I lcm (const cl_I& a, const cl_I& b);
0509
0510
0511
0512
0513
0514
0515
0516
0517
0518 extern bool isqrt (const cl_I& x, cl_I* w);
0519
0520 inline const cl_I isqrt (const cl_I& x) { cl_I w; isqrt(x,&w); return w; }
0521
0522
0523
0524
0525
0526
0527 extern bool sqrtp (const cl_I& x, cl_I* w);
0528
0529
0530
0531
0532
0533
0534
0535 extern bool rootp (const cl_I& x, uintL n, cl_I* w);
0536 extern bool rootp (const cl_I& x, const cl_I& n, cl_I* w);
0537
0538
0539
0540 extern const cl_I max (const cl_I& x, const cl_I& y);
0541
0542
0543 extern const cl_I min (const cl_I& x, const cl_I& y);
0544
0545
0546 extern const cl_I signum (const cl_I& x);
0547
0548
0549
0550
0551
0552
0553
0554 extern const cl_I mul_10_plus_x (const cl_I& y, unsigned char x);
0555
0556
0557
0558
0559
0560
0561
0562 extern const cl_I cl_recip2adic (uintL n, const cl_I& x);
0563
0564
0565
0566
0567
0568
0569
0570 extern const cl_I cl_div2adic (uintL n, const cl_I& x, const cl_I& y);
0571
0572
0573
0574 inline const cl_I numerator (const cl_I& r)
0575 { return r; }
0576
0577 inline const cl_I denominator (const cl_I& r)
0578 { (void)r; return 1; }
0579
0580
0581
0582 extern float float_approx (const cl_I& x);
0583
0584
0585 extern double double_approx (const cl_I& x);
0586
0587
0588
0589
0590
0591 extern const cl_I random_I (random_state& randomstate, const cl_I& n);
0592
0593 inline const cl_I random_I (const cl_I& n)
0594 { return random_I(default_random_state,n); }
0595
0596
0597
0598 extern const cl_I testrandom_I (random_state& randomstate);
0599
0600 inline const cl_I testrandom_I ()
0601 { return testrandom_I(default_random_state); }
0602
0603
0604
0605 inline cl_I& operator+= (cl_I& x, const cl_I& y) { return x = x + y; }
0606 inline cl_I& operator+= (cl_I& x, const int y) { return x = x + y; }
0607 inline cl_I& operator+= (cl_I& x, const unsigned int y) { return x = x + y; }
0608 inline cl_I& operator+= (cl_I& x, const long y) { return x = x + y; }
0609 inline cl_I& operator+= (cl_I& x, const unsigned long y) { return x = x + y; }
0610 inline cl_I& operator++ (cl_I& x) { return x = plus1(x); }
0611 inline void operator++ (cl_I& x, int dummy) { (void)dummy; x = plus1(x); }
0612 inline cl_I& operator-= (cl_I& x, const cl_I& y) { return x = x - y; }
0613 inline cl_I& operator-= (cl_I& x, const int y) { return x = x - y; }
0614 inline cl_I& operator-= (cl_I& x, const unsigned int y) { return x = x - y; }
0615 inline cl_I& operator-= (cl_I& x, const long y) { return x = x - y; }
0616 inline cl_I& operator-= (cl_I& x, const unsigned long y) { return x = x - y; }
0617 inline cl_I& operator-- (cl_I& x) { return x = minus1(x); }
0618 inline void operator-- (cl_I& x, int dummy) { (void)dummy; x = minus1(x); }
0619 inline cl_I& operator*= (cl_I& x, const cl_I& y) { return x = x * y; }
0620 inline cl_I& operator<<= (cl_I& x, sintC y)
0621 { return x = x << y; }
0622 inline cl_I& operator<<= (cl_I& x, const cl_I& y)
0623 { return x = x << y; }
0624 inline cl_I& operator>>= (cl_I& x, sintC y)
0625 { return x = x >> y; }
0626 inline cl_I& operator>>= (cl_I& x, const cl_I& y)
0627 { return x = x >> y; }
0628 #if 0
0629
0630
0631
0632
0633 inline const cl_I operator/ (const cl_I& x, const cl_I& y) { return truncate1(x,y); }
0634 inline const cl_I operator% (const cl_I& x, const cl_I& y) { return rem(x,y); }
0635 inline cl_I& operator/= (cl_I& x, const cl_I& y) { return x = x / y; }
0636 inline cl_I& operator%= (cl_I& x, const cl_I& y) { return x = x % y; }
0637 #endif
0638
0639
0640
0641 extern cl_class cl_class_fixnum;
0642 extern cl_class cl_class_bignum;
0643 CL_FORCE_LINK(cl_I_classes_dummy, cl_class_fixnum)
0644
0645
0646
0647 #ifdef CL_DEBUG
0648 extern int cl_I_debug_module;
0649 CL_FORCE_LINK(cl_I_debug_dummy, cl_I_debug_module)
0650 #endif
0651
0652 }
0653
0654 #endif