handel, by truncation, verinums that are to long for long integers.

This commit is contained in:
steve 2000-09-28 03:55:55 +00:00
parent fff759de20
commit 700bcfda70
1 changed files with 49 additions and 36 deletions

View File

@ -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
*/ */
#if !defined(WINNT) && !defined(macintosh) #if !defined(WINNT) && !defined(macintosh)
#ident "$Id: verinum.cc,v 1.19 2000/09/27 18:28:37 steve Exp $" #ident "$Id: verinum.cc,v 1.20 2000/09/28 03:55:55 steve Exp $"
#endif #endif
# include "verinum.h" # include "verinum.h"
@ -135,56 +135,66 @@ verinum::V verinum::set(unsigned idx, verinum::V val)
unsigned long verinum::as_ulong() const unsigned long verinum::as_ulong() const
{ {
assert(nbits_ <= 8 * sizeof(unsigned long));
if (nbits_ == 0) if (nbits_ == 0)
return 0; return 0;
if (!is_defined())
return 0;
unsigned top = nbits_;
if (top >= (8 * sizeof(unsigned long)))
top = 8 * sizeof(unsigned long);
unsigned long val = 0; unsigned long val = 0;
for (unsigned idx = nbits_ ; idx > 0 ; idx -= 1) { unsigned long mask = 1;
val <<= 1; for (unsigned idx = 0 ; idx < top ; idx += 1, mask <<= 1)
switch (bits_[idx-1]) { if (bits_[idx] == V1)
case V0: val |= mask;
break;
case V1:
val |= 1;
break;
case Vx:
case Vz:
// what should I do here? Throw an exception?
break;
}
}
return val; return val;
} }
/*
* This function returns the native long integer that represents the
* value of this object. It accounts for sign extension if the value
* is signed.
*
* If the value is undefined, return 0.
*
* This function presumes that the native format is 2s compliment
* (pretty safe these days) and masks/sets bits accordingly. If the
* value is too large for the lative form, it truncates the high bits.
*/
signed long verinum::as_long() const signed long verinum::as_long() const
{ {
assert(nbits_ <= 8 * sizeof(signed long));
if (nbits_ == 0) if (nbits_ == 0)
return 0; return 0;
if (!is_defined())
return 0;
signed long val = 0; signed long val = 0;
// Extend the sign bit to fill the long. (But only for signed if (has_sign_ && (bits_[nbits_-1] == V1)) {
// numbers.) unsigned top = nbits_;
if (has_sign_ && (bits_[nbits_-1] == V1)) if (top > (8 * sizeof(long) - 1))
val = -1; top = 8 * sizeof(long) - 1;
for (unsigned idx = nbits_ ; idx > 0 ; idx -= 1) { val = -1;
val <<= 1; signed long mask = ~1L;
switch (bits_[idx-1]) { for (unsigned idx = 0 ; idx < top ; idx += 1, mask <<= 1)
case V0: if (bits_[idx] == V0)
break; val &= mask;
case V1:
val |= 1; } else {
break; unsigned top = nbits_;
case Vx: if (top > (8 * sizeof(long) - 1))
case Vz: top = 8 * sizeof(long) - 1;
// what should I do here? Throw an exception?
break; signed long mask = 1;
} for (unsigned idx = 0 ; idx < top ; idx += 1, mask <<= 1)
if (bits_[idx] == V1)
val |= mask;
} }
return val; return val;
@ -521,6 +531,9 @@ verinum operator * (const verinum&left, const verinum&right)
/* /*
* $Log: verinum.cc,v $ * $Log: verinum.cc,v $
* Revision 1.20 2000/09/28 03:55:55 steve
* handel, by truncation, verinums that are to long for long integers.
*
* Revision 1.19 2000/09/27 18:28:37 steve * Revision 1.19 2000/09/27 18:28:37 steve
* multiply in parameter expressions. * multiply in parameter expressions.
* *