Handle very wide signed divide.
This commit is contained in:
parent
2eeea7003e
commit
4fb5556d1c
42
verinum.cc
42
verinum.cc
|
|
@ -17,7 +17,7 @@
|
||||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||||
*/
|
*/
|
||||||
#ifdef HAVE_CVS_IDENT
|
#ifdef HAVE_CVS_IDENT
|
||||||
#ident "$Id: verinum.cc,v 1.48 2006/08/08 05:11:37 steve Exp $"
|
#ident "$Id: verinum.cc,v 1.49 2006/12/08 19:56:09 steve Exp $"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
# include "config.h"
|
# include "config.h"
|
||||||
|
|
@ -878,16 +878,33 @@ verinum operator / (const verinum&left, const verinum&right)
|
||||||
result is signed or not. */
|
result is signed or not. */
|
||||||
if (result.has_sign()) {
|
if (result.has_sign()) {
|
||||||
|
|
||||||
/* XXXX FIXME XXXX Use native unsigned division to do
|
if (use_len <= 8*sizeof(long)) {
|
||||||
the work. This does not work if the result is too
|
long l = left.as_long();
|
||||||
large for the native integer. */
|
long r = right.as_long();
|
||||||
assert(use_len <= 8*sizeof(long));
|
long v = l / r;
|
||||||
long l = left.as_long();
|
for (unsigned idx = 0 ; idx < use_len ; idx += 1) {
|
||||||
long r = right.as_long();
|
result.set(idx, (v & 1)? verinum::V1 : verinum::V0);
|
||||||
long v = l / r;
|
v >>= 1;
|
||||||
for (unsigned idx = 0 ; idx < use_len ; idx += 1) {
|
}
|
||||||
result.set(idx, (v & 1)? verinum::V1 : verinum::V0);
|
|
||||||
v >>= 1;
|
} else {
|
||||||
|
verinum use_left, use_right;
|
||||||
|
verinum zero(verinum::V0, 1, false);
|
||||||
|
bool negative = false;
|
||||||
|
if (left < zero) {
|
||||||
|
use_left = zero - left;
|
||||||
|
negative ^= negative;
|
||||||
|
} else {
|
||||||
|
use_left = left;
|
||||||
|
}
|
||||||
|
if (right < zero) {
|
||||||
|
use_right = zero - right;
|
||||||
|
negative ^= negative;
|
||||||
|
} else {
|
||||||
|
use_right = right;
|
||||||
|
}
|
||||||
|
result = unsigned_divide(use_left, use_right);
|
||||||
|
if (negative) result = zero - result;
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -1039,6 +1056,9 @@ verinum::V operator ^ (verinum::V l, verinum::V r)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* $Log: verinum.cc,v $
|
* $Log: verinum.cc,v $
|
||||||
|
* Revision 1.49 2006/12/08 19:56:09 steve
|
||||||
|
* Handle very wide signed divide.
|
||||||
|
*
|
||||||
* Revision 1.48 2006/08/08 05:11:37 steve
|
* Revision 1.48 2006/08/08 05:11:37 steve
|
||||||
* Handle 64bit delay constants.
|
* Handle 64bit delay constants.
|
||||||
*
|
*
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue