3
Copyright (C) 1994 M. Hagiya, W. Schelter, T. Yuasa
5
This file is part of GNU Common Lisp, herein referred to as GCL
7
GCL is free software; you can redistribute it and/or modify it under
8
the terms of the GNU LIBRARY GENERAL PUBLIC LICENSE as published by
9
the Free Software Foundation; either version 2, or (at your option)
12
GCL is distributed in the hope that it will be useful, but WITHOUT
13
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14
FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
15
License for more details.
17
You should have received a copy of the GNU Library General Public License
18
along with GCL; see the file COPYING. If not, write to the Free Software
19
Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
24
Logical operations on number
29
#include "num_include.h"
33
#include "gmp_num_log.c"
35
#include "pari_num_log.c"
76
andc1_op(int i, int j)
82
andc2_op(int i, int j)
100
b_clr_op(int i, int j)
106
b_set_op(int i, int j)
124
b_c1_op(int i, int j)
130
b_c2_op(int i, int j)
136
int (*intLogOps)()[16]= {
158
fix_bitp(object x, int p)
160
if (p > 30) { /* fix = sign + bit0-30 */
166
return((fix(x) >> p) & 1);
170
count_int_bits(int x)
175
for (i=0; i <= 31; i++) count += ((x >> i) & 1);
184
if (type_of(x) == t_fixnum) {
187
count = count_int_bits(i);
188
} else if (type_of(x) == t_bignum)
190
count= MP_BITCOUNT(MP(x));
193
FEwrong_type_argument(sLinteger, x);
198
double_shift(h, l, w, hp, lp) shifts the int h & l ( 31 bits)
199
w bits to left ( w > 0) or to right ( w < 0).
200
result is returned in *hp and *lp.
206
shift_integer(object x, int w)
208
if (type_of(x) == t_fixnum)
211
if (w >= WSIZ) return small_fixnum(fix(x) < 0 ? -1 :0);
213
return make_fixnum (fix(x) >> (w));}
214
MPOP(return, shifti,SI_TO_MP(fix(x),big_fixnum1),w);
217
if (type_of(x) == t_bignum) {
218
MPOP(return,shifti,MP(x),w);
220
FEwrong_type_argument(sLinteger, x);
226
int_bit_length(int i)
231
for (j = 0; j <= 31 ; j++)
232
if (((i >> j) & 1) == 1) count = j + 1;
242
int ior_op(int i, int j);
244
narg = vs_top - vs_base;
245
for (i = 0; i < narg; i++)
246
check_type_integer(&vs_base[i]);
249
vs_push(small_fixnum(0));
254
x = log_op(ior_op,mp_ior_op);
263
int xor_op(int i, int j);
265
narg = vs_top - vs_base;
266
for (i = 0; i < narg; i++)
267
check_type_integer(&vs_base[i]);
270
vs_push(small_fixnum(0));
273
if (narg == 1) return;
274
x = log_op(xor_op,mp_xor_op);
283
int and_op(int i, int j);
285
narg = vs_top - vs_base;
286
for (i = 0; i < narg; i++)
287
check_type_integer(&vs_base[i]);
290
vs_push(small_fixnum(-1));
293
if (narg == 1) return;
294
x = log_op(and_op,mp_and_op);
303
int eqv_op(int i, int j);
305
narg = vs_top - vs_base;
306
for (i = 0; i < narg; i++)
307
check_type_integer(&vs_base[i]);
310
vs_push(small_fixnum(-1));
313
if (narg == 1) return;
314
x = log_op(eqv_op,mp_eqv_op);
324
void (*mp_op)() = (void *) 0;
327
check_type_integer(&vs_base[0]);
328
check_type_integer(&vs_base[1]);
329
check_type_integer(&vs_base[2]);
333
case BOOLCLR: op = b_clr_op; mp_op = mp_b_clr_op; break;
334
case BOOLSET: op = b_set_op; mp_op = mp_b_set_op; break;
335
case BOOL1: op = b_1_op; mp_op = mp_b_1_op; break;
336
case BOOL2: op = b_2_op; mp_op = mp_b_2_op; break;
337
case BOOLC1: op = b_c1_op; mp_op =mp_b_c1_op; break;
338
case BOOLC2: op = b_c2_op; mp_op =mp_b_c2_op; break;
339
case BOOLAND: op = and_op; mp_op = mp_and_op; break;
340
case BOOLIOR: op = ior_op; mp_op = mp_ior_op; break;
341
case BOOLXOR: op = xor_op; mp_op = mp_xor_op; break;
342
case BOOLEQV: op = eqv_op; mp_op = mp_eqv_op; break;
343
case BOOLNAND: op = nand_op; mp_op =mp_nand_op; break;
344
case BOOLNOR: op = nor_op; mp_op = mp_nor_op; break;
345
case BOOLANDC1: op = andc1_op; mp_op = mp_andc1_op; break;
346
case BOOLANDC2: op = andc2_op; mp_op = mp_andc2_op; break;
347
case BOOLORC1: op = orc1_op; mp_op =mp_orc1_op; break;
348
case BOOLORC2: op = orc2_op; mp_op =mp_orc2_op; break;
350
FEerror("~S is an invalid logical operator.",
354
x = log_op(op,mp_op);
366
check_type_integer(&vs_base[0]);
367
check_type_integer(&vs_base[1]);
370
if (type_of(p) == t_fixnum)
371
if (type_of(x) == t_fixnum)
372
i = fix_bitp(x, fix(p));
374
i = big_bitp(x, fix(p));
375
else if (big_sign(p) < 0)
378
bit position represented by bignum is out of
379
our address space. So, result is returned
380
according to sign of integer.
383
else if (type_of(x) == t_fixnum)
388
else if (big_sign(x) < 0)
406
check_type_integer(&vs_base[0]);
407
check_type_integer(&vs_base[1]);
410
if (type_of(y) == t_fixnum) {
412
r = shift_integer(x, w);
413
} else if (type_of(y) == t_bignum)
420
bit position represented by bignum is probably
421
out of our address space. So, result is returned
422
according to sign of integer.
425
if (type_of(x) == t_fixnum)
428
else if (fix(x) == 0)
433
sign_x = big_sign(x);
436
r = small_fixnum(-1);
439
else if (sign_x == 0)
442
FEerror("Insufficient memory.", 0);
455
check_type_integer(&vs_base[0]);
459
vs_push(make_fixnum(i));
462
LFD(Linteger_length)(void)
469
if (type_of(x) == t_fixnum) {
472
count = int_bit_length(i);
473
} else if (type_of(x) == t_bignum)
474
count = MP_SIZE_IN_BASE2(MP(x));
476
FEwrong_type_argument(sLinteger, x);
478
vs_push(make_fixnum(count));
481
#define W_SIZE (8*sizeof(int))
483
/* bitand(object a, object b, object c) */
484
/* { int d= a->bv.bv_fillp; */
485
/* int *ap,*bp,*cp; */
486
/* d=(d+W_SIZE-1)/W_SIZE; */
487
/* ap= (int *)(a->bv.bv_self); */
488
/* bp= (int *)(b->bv.bv_self); */
489
/* cp= (int *)(c->bv.bv_self); */
490
/* while (--d >= 0) */
491
/* { *cp++ = *bp++ & *ap++; */
497
/* bitior(object a, object b, object c) */
498
/* { int *ap,*cp,*bp, d= a->bv.bv_fillp; */
499
/* d=(d+W_SIZE-1)/W_SIZE; */
500
/* ap= (int *)((a->bv.bv_self)); */
501
/* bp= (int *)(b->bv.bv_self); */
502
/* cp= (int *)(c->bv.bv_self); */
503
/* while (--d >= 0) */
504
/* { *cp++ = *bp++ | *ap++; */
509
/* Note in order to be equal we assume that the part above the
510
fill pointer is 0 up to the next word */
513
/* bvequal(object a, object b) */
514
/* { int *ap,*bp, d= a->bv.bv_fillp; */
515
/* d=(d+W_SIZE-1)/W_SIZE; */
516
/* ap= (int *)(a->bv.bv_self); */
517
/* bp= (int *)(b->bv.bv_self); */
518
/* while (--d >= 0) */
519
/* { if (*ap++ != *bp++) return 1; */
526
LFD(siLbit_array_op)(void)
529
object o, x, y, r, r0=Cnil;
531
bool replace = FALSE;
535
object *base = vs_base;
542
if (type_of(x) == t_bitvector) {
546
if (type_of(y) != t_bitvector)
548
if (d != y->bv.bv_dim)
555
if (type_of(r) != t_bitvector)
557
if (r->bv.bv_dim != d)
559
i = (r->bv.bv_self - xp)*8 + (BV_OFFSET(r) - xo);
560
if ((i > 0 && i < d) || (i < 0 && -i < d)) {
566
i = (r->bv.bv_self - yp)*8 + (BV_OFFSET(r) - yo);
567
if ((i > 0 && i < d) || (i < 0 && -i < d)) {
577
vs_push(make_fixnum(d));
587
if (type_of(x) != t_array)
589
if ((enum aelttype)x->a.a_elttype != aet_bit)
594
if (type_of(y) != t_array)
596
if ((enum aelttype)y->a.a_elttype != aet_bit)
598
if (x->a.a_rank != y->a.a_rank)
602
for (i = 0; i < x->a.a_rank; i++)
603
if (x->a.a_dims[i] != y->a.a_dims[i])
608
if (type_of(r) != t_array)
610
if ((enum aelttype)r->a.a_elttype != aet_bit)
612
if (r->a.a_rank != x->a.a_rank)
614
for (i = 0; i < x->a.a_rank; i++)
615
if (r->a.a_dims[i] != x->a.a_dims[i])
617
i = (r->bv.bv_self - xp)*8 + (BV_OFFSET(r) - xo);
618
if ((i > 0 && i < d) || (i < 0 && -i < d)) {
624
i = (r->bv.bv_self - yp)*8 + (BV_OFFSET(r) - yo);
625
if ((i > 0 && i < d) || (i < 0 && -i < d)) {
634
struct cons *p=alloca(x->a.a_rank*sizeof(struct cons));
639
for (b1=b,i=0;i<x->a.a_rank;i++,b1=b1->c.c_cdr) {
642
b1->c.c_car=/* x->a.a_dims[i]<SMALL_FIXNUM_LIMIT ? */
643
/* small_fixnum(x->a.a_dims[i]) : */
644
/* now done in a macro */
645
make_fixnum(x->a.a_dims[i]);
646
b1->c.c_cdr=i<x->a.a_rank-1 ? (object)++p : Cnil;
651
r = fSmake_array1(aet_bit,Cnil,small_fixnum(0),Cnil,0,b);
653
/* object b[F_ARG_LIMIT]; */
655
/* for (i = 0; i < x->a.a_rank; i++) */
656
/* b[i] = (make_fixnum(x->a.a_dims[i])); */
657
/* r=Iapply_fun_n1(fSmake_array1,5,x->a.a_rank ? x->a.a_rank : 1, */
660
/* small_fixnum(0), */
670
case BOOLCLR: op = b_clr_op; break;
671
case BOOLSET: op = b_set_op; break;
672
case BOOL1: op = b_1_op; break;
673
case BOOL2: op = b_2_op; break;
674
case BOOLC1: op = b_c1_op; break;
675
case BOOLC2: op = b_c2_op; break;
676
case BOOLAND: op = and_op; break;
677
case BOOLIOR: op = ior_op; break;
678
case BOOLXOR: op = xor_op; break;
679
case BOOLEQV: op = eqv_op; break;
680
case BOOLNAND: op = nand_op; break;
681
case BOOLNOR: op = nor_op; break;
682
case BOOLANDC1: op = andc1_op; break;
683
case BOOLANDC2: op = andc2_op; break;
684
case BOOLORC1: op = orc1_op; break;
685
case BOOLORC2: op = orc2_op; break;
687
FEerror("~S is an invalid logical operator.", 1, o);
690
#define set_high(place, nbits, value) \
691
((place)=(((place)&~(-0400>>(nbits)))|((value)&(-0400>>(nbits)))))
693
#define set_low(place, nbits, value) \
694
((place)=(((place)&(-0400>>(8-(nbits))))|((value)&~(-0400>>(8-(nbits))))))
696
#define extract_byte(integer, pointer, index, offset) \
697
(integer) = (pointer)[(index)+1] & 0377; \
698
(integer) = ((pointer)[index]<<(offset))|((integer)>>(8-(offset)))
700
#define store_byte(pointer, index, offset, value) \
701
set_low((pointer)[index], 8-(offset), (value)>>(offset)); \
702
set_high((pointer)[(index)+1], offset, (value)<<(8-(offset)))
704
if (xo == 0 && yo == 0 && ro == 0) {
705
for (n = d/8, i = 0; i < n; i++)
706
rp[i] = (*op)(xp[i], yp[i]);
708
set_high(rp[n], j, (*op)(xp[n], yp[n]));
710
vs_top = vs_base = base;
715
for (n = d/8, i = 0; i <= n; i++) {
716
extract_byte(xi, xp, i, xo);
717
extract_byte(yi, yp, i, yo);
721
extract_byte(ri, rp, n, ro);
722
set_high(ri, j, (*op)(xi, yi));
725
store_byte(rp, i, ro, ri);
728
vs_top = vs_base = base;
735
for (n = d/8, i = 0; i <= n; i++) {
739
extract_byte(ri, rp, n, ro);
740
set_high(ri, j, r->bv.bv_self[n]);
742
ri = r->bv.bv_self[i];
743
store_byte(rp, i, ro, ri);
745
vs_top = vs_base = base;
750
FEerror("Illegal arguments for bit-array operation.", 0);
754
gcl_init_num_log(void)
756
/* int siLbit_array_op(void); */
758
make_constant("BOOLE-CLR", make_fixnum(BOOLCLR));
759
make_constant("BOOLE-SET", make_fixnum(BOOLSET));
760
make_constant("BOOLE-1", make_fixnum(BOOL1));
761
make_constant("BOOLE-2", make_fixnum(BOOL2));
762
make_constant("BOOLE-C1", make_fixnum(BOOLC1));
763
make_constant("BOOLE-C2", make_fixnum(BOOLC2));
764
make_constant("BOOLE-AND", make_fixnum(BOOLAND));
765
make_constant("BOOLE-IOR", make_fixnum(BOOLIOR));
766
make_constant("BOOLE-XOR", make_fixnum(BOOLXOR));
767
make_constant("BOOLE-EQV", make_fixnum(BOOLEQV));
768
make_constant("BOOLE-NAND", make_fixnum(BOOLNAND));
769
make_constant("BOOLE-NOR", make_fixnum(BOOLNOR));
770
make_constant("BOOLE-ANDC1", make_fixnum(BOOLANDC1));
771
make_constant("BOOLE-ANDC2", make_fixnum(BOOLANDC2));
772
make_constant("BOOLE-ORC1", make_fixnum(BOOLORC1));
773
make_constant("BOOLE-ORC2", make_fixnum(BOOLORC2));
775
make_function("LOGIOR", Llogior);
776
make_function("LOGXOR", Llogxor);
777
make_function("LOGAND", Llogand);
778
make_function("LOGEQV", Llogeqv);
779
make_function("BOOLE", Lboole);
780
make_function("LOGBITP", Llogbitp);
781
make_function("ASH", Lash);
782
make_function("LOGCOUNT", Llogcount);
783
make_function("INTEGER-LENGTH", Linteger_length);
785
sLbit = make_ordinary("BIT");
786
make_si_function("BIT-ARRAY-OP", siLbit_array_op);