/* -*-c-*-
*
- * $Id: mpx.c,v 1.12 2002/10/06 22:52:50 mdw Exp $
+ * $Id: mpx.c,v 1.15 2002/10/20 01:12:31 mdw Exp $
*
* Low-level multiprecision arithmetic
*
/*----- Revision history --------------------------------------------------*
*
* $Log: mpx.c,v $
+ * Revision 1.15 2002/10/20 01:12:31 mdw
+ * Two's complement I/O fixes.
+ *
+ * Revision 1.14 2002/10/19 18:55:08 mdw
+ * Fix overflows in shift primitives.
+ *
+ * Revision 1.13 2002/10/19 17:56:50 mdw
+ * Fix bit operations. Test them (a bit) better.
+ *
* Revision 1.12 2002/10/06 22:52:50 mdw
* Pile of changes for supporting two's complement properly.
*
#include "mptypes.h"
#include "mpx.h"
+#include "bitops.h"
/*----- Loading and storing -----------------------------------------------*/
bits -= 8;
}
b = U8(~b + c);
- c = !b;
+ c = c && !b;
*p++ = b;
}
while (p < q) {
b = U8(~b + c);
- c = !b;
+ c = c && !b;
*p++ = b;
b = 0;
}
return;
while (p < q) {
n = U8(~(*p++) + c);
- c = !n;
+ c = c && !n;
w |= n << bits;
bits += 8;
if (bits >= MPW_BITS) {
bits -= 8;
}
b = U8(~b + c);
- c = !b;
+ c = c && !b;
*--q = b;
}
while (q > p) {
b = ~b + c;
- c = !(b & 0xff);
+ c = c && !(b & 0xff);
*--q = b;
b = 0;
}
return;
while (q > p) {
n = U8(~(*--q) + c);
- c = !n;
+ c = c && !n;
w |= n << bits;
bits += 8;
if (bits >= MPW_BITS) {
/* --- Handle a shift by a multiple of the word size --- */
if (nb == 0) {
- MPX_COPY(dv + nw, dvl, av, avl);
- memset(dv, 0, MPWS(nw));
+ if (nw >= dvl - dv)
+ MPX_ZERO(dv, dvl);
+ else {
+ MPX_COPY(dv + nw, dvl, av, avl);
+ memset(dv, 0, MPWS(nw));
+ }
}
/* --- And finally the difficult case --- *
/* --- Handle a shift by a multiple of the word size --- */
- if (nb == 0)
- MPX_COPY(dv, dvl, av + nw, avl);
+ if (nb == 0) {
+ if (nw >= avl - av)
+ MPX_ZERO(dv, dvl);
+ else
+ MPX_COPY(dv, dvl, av + nw, avl);
+ }
/* --- And finally the difficult case --- */
size_t nr = MPW_BITS - nb;
av += nw;
- w = *av++;
+ w = av < avl ? *av++ : 0;
while (av < avl) {
mpw t;
if (dv >= dvl)
mpw a, b; \
a = (av < avl) ? *av++ : 0; \
b = (bv < bvl) ? *bv++ : 0; \
- *dv++ = MPX_B##string(a, b); \
+ *dv++ = B##string(a, b); \
} \
}