diff options
author | Nathan Binkert <binkertn@umich.edu> | 2003-10-31 18:27:17 -0500 |
---|---|---|
committer | Nathan Binkert <binkertn@umich.edu> | 2003-10-31 18:27:17 -0500 |
commit | 5341e1aa9e3562d5217f3db87ca77238bf63f93e (patch) | |
tree | b161a2c80994b44fe28ea0184b1cf73837288fcc /base/str.cc | |
parent | 8835aae3e3a4a4830b8cb03a7eefaa429ff63173 (diff) | |
download | gem5-5341e1aa9e3562d5217f3db87ca77238bf63f93e.tar.xz |
Make the to_number function work better.
base/str.cc:
Make some fixes for the to_number function.
Fix overflow calculation for maximum decimal value.
(Note: minimum decimal value for signed numbers does not
work correctly, e.g. it will overflow on -128 for a signed char
though -127 will work)
Fix overflow calculation for hex values being converted into
signed types
Fix up the debugging stuff a little to make sure the values are
always printed as numbers.
test/strnumtest.cc:
using namespace std for g++ 3
--HG--
extra : convert_revision : b00bb1296c85c3d64d8864283c9374e1563bfa31
Diffstat (limited to 'base/str.cc')
-rw-r--r-- | base/str.cc | 30 |
1 files changed, 20 insertions, 10 deletions
diff --git a/base/str.cc b/base/str.cc index 9c3964ce3..5ba23b55f 100644 --- a/base/str.cc +++ b/base/str.cc @@ -74,25 +74,31 @@ tokenize(vector<string>& v, const string &s, char token, bool ignore) v.push_back(s.substr(first)); } +/** + * @todo This function will not handle the smallest negative decimal + * value for a signed type + */ + template <class T> inline bool __to_number(string value, T &retval) { static const T maxnum = ((T)-1); static const bool sign = maxnum < 0; - static const T hexmax = maxnum & (((T)1 << (sizeof(T) * 8 - 4)) - 1); - static const T octmax = maxnum & (((T)1 << (sizeof(T) * 8 - 3)) - 1); + static const int bits = sizeof(T) * 8; + static const T hexmax = maxnum & (((T)1 << (bits - 4 - sign)) - 1); + static const T octmax = maxnum & (((T)1 << (bits - 3 - sign)) - 1); static const T signmax = - (sign) ? maxnum & (((T)1 << (sizeof(T) * 8 - 1)) - 1) : maxnum; - static const T decmax = signmax / 10 - 1; + (sign) ? maxnum & (((T)1 << (bits - 1)) - 1) : maxnum; + static const T decmax = signmax / 10; #if 0 - cout << "maxnum = 0x" << hex << maxnum << "\n" - << "sign = 0x" << hex << sign << "\n" - << "hexmax = 0x" << hex << hexmax << "\n" - << "octmax = 0x" << hex << octmax << "\n" - << "signmax = 0x" << hex << signmax << "\n" - << "decmax = 0x" << hex << decmax << "\n"; + cout << "maxnum = 0x" << hex << (unsigned long long)maxnum << "\n" + << "sign = 0x" << hex << (unsigned long long)sign << "\n" + << "hexmax = 0x" << hex << (unsigned long long)hexmax << "\n" + << "octmax = 0x" << hex << (unsigned long long)octmax << "\n" + << "signmax = 0x" << hex << (unsigned long long)signmax << "\n" + << "decmax = 0x" << hex << (unsigned long long)decmax << "\n"; #endif eat_white(value); @@ -180,8 +186,10 @@ __to_number(string value, T &retval) goto multiply; if (retval > decmax) return false; + bool atmax = retval == decmax; retval *= 10; retval += c - '0'; + if (atmax && retval < decmax) return false; if (sign && (retval & ((T)1 << (sizeof(T) * 8 - 1)))) return false; } @@ -190,8 +198,10 @@ __to_number(string value, T &retval) if (IsDec(c)) { if (retval > decmax) return false; + bool atmax = retval == decmax; retval *= 10; retval += c - '0'; + if (atmax && retval < decmax) return false; if (sign && negative) { if ((retval & ((T)1 << (sizeof(T) * 8 - 1))) && retval >= (T)-signmax) |