Make the to_number function work better.
authorNathan Binkert <binkertn@umich.edu>
Fri, 31 Oct 2003 23:27:17 +0000 (18:27 -0500)
committerNathan Binkert <binkertn@umich.edu>
Fri, 31 Oct 2003 23:27:17 +0000 (18:27 -0500)
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

base/str.cc
test/strnumtest.cc

index 9c3964ce3822986740f39cfb8c02209b8da4fc73..5ba23b55f72e8299611140d23742dd2c40ad874a 100644 (file)
@@ -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)
index e971a7dfd863d252903719591eb0ee68daaf6a3f..d491b8b5d97821961b7a9dc9e7460ada9d374c13 100644 (file)
@@ -33,6 +33,8 @@
 
 #include "base/str.hh"
 
+using namespace std;
+
 int
 main(int argc, char *argv[])
 {