changeset 458:39f8c9430b2d draft

Merge branch 'rounding'
author Gavin Andresen <gavinandresen@gmail.com>
date Wed, 02 Mar 2011 15:03:49 -0500
parents 489d0c2d7a7c (current diff) caf8330369a9 (diff)
children 91b031e90a14 c8fd1ed13260 5bacf0e14b72
files
diffstat 2 files changed, 34 insertions(+), 24 deletions(-) [+]
line wrap: on
line diff
--- a/rpc.cpp
+++ b/rpc.cpp
@@ -65,7 +65,7 @@
     double dAmount = value.get_real();
     if (dAmount <= 0.0 || dAmount > 21000000.0)
         throw JSONRPCError(-3, "Invalid amount");
-    int64 nAmount = roundint64(dAmount * 100.00) * CENT;
+    int64 nAmount = roundint64(dAmount * COIN);
     if (!MoneyRange(nAmount))
         throw JSONRPCError(-3, "Invalid amount");
     return nAmount;
@@ -277,7 +277,7 @@
 
     Object obj;
     obj.push_back(Pair("version",       (int)VERSION));
-    obj.push_back(Pair("balance",       (double)GetBalance() / (double)COIN));
+    obj.push_back(Pair("balance",       ValueFromAmount(GetBalance())));
     obj.push_back(Pair("blocks",        (int)nBestHeight));
     obj.push_back(Pair("connections",   (int)vNodes.size()));
     obj.push_back(Pair("proxy",         (fUseProxy ? addrProxy.ToStringIPPort() : string())));
@@ -287,7 +287,7 @@
     obj.push_back(Pair("hashespersec",  gethashespersec(params, false)));
     obj.push_back(Pair("testnet",       fTestNet));
     obj.push_back(Pair("keypoololdest", (boost::int64_t)GetOldestKeyPoolTime()));
-    obj.push_back(Pair("paytxfee",      (double)nTransactionFee / (double)COIN));
+    obj.push_back(Pair("paytxfee",      ValueFromAmount(nTransactionFee)));
     obj.push_back(Pair("errors",        GetWarnings("statusbar")));
     return obj;
 }
@@ -513,7 +513,7 @@
         }
     }
 
-    return (double)nAmount / (double)COIN;
+    return  ValueFromAmount(nAmount);
 }
 
 
@@ -619,7 +619,7 @@
             "If [account] is specified, returns the balance in the account.");
 
     if (params.size() == 0)
-        return ((double)GetBalance() / (double)COIN);
+        return  ValueFromAmount(GetBalance());
 
     if (params[0].get_str() == "*") {
         // Calculate total balance a different way from GetBalance()
@@ -648,7 +648,7 @@
             nBalance += allGenerated;
         }
         printf("Found %d accounts\n", vAccounts.size());
-        return (double)nBalance / (double)COIN;
+        return  ValueFromAmount(nBalance);
     }
 
     string strAccount = AccountFromValue(params[0]);
@@ -658,7 +658,7 @@
 
     int64 nBalance = GetAccountBalance(strAccount, nMinDepth);
 
-    return (double)nBalance / (double)COIN;
+    return ValueFromAmount(nBalance);
 }
 
 
@@ -851,7 +851,7 @@
                 obj.push_back(Pair("address",       strAddress));
                 obj.push_back(Pair("account",       strAccount));
                 obj.push_back(Pair("label",         strAccount)); // deprecated
-                obj.push_back(Pair("amount",        (double)nAmount / (double)COIN));
+                obj.push_back(Pair("amount",        ValueFromAmount(nAmount)));
                 obj.push_back(Pair("confirmations", (nConf == INT_MAX ? 0 : nConf)));
                 ret.push_back(obj);
             }
@@ -867,7 +867,7 @@
             Object obj;
             obj.push_back(Pair("account",       (*it).first));
             obj.push_back(Pair("label",         (*it).first)); // deprecated
-            obj.push_back(Pair("amount",        (double)nAmount / (double)COIN));
+            obj.push_back(Pair("amount",        ValueFromAmount(nAmount)));
             obj.push_back(Pair("confirmations", (nConf == INT_MAX ? 0 : nConf)));
             ret.push_back(obj);
         }
--- a/util.cpp
+++ b/util.cpp
@@ -313,9 +313,23 @@
 
 string FormatMoney(int64 n, bool fPlus)
 {
-    n /= CENT;
-    string str = strprintf("%"PRI64d".%02"PRI64d, (n > 0 ? n : -n)/100, (n > 0 ? n : -n)%100);
-    for (int i = 6; i < str.size(); i += 4)
+    // Note: not using straight sprintf here because we do NOT want
+    // localized number formatting.
+    int64 n_abs = (n > 0 ? n : -n);
+    int64 quotient = n_abs/COIN;
+    int64 remainder = n_abs%COIN;
+    string str = strprintf("%"PRI64d".%08"PRI64d, quotient, remainder);
+
+    // Right-trim excess 0's before the decimal point:
+    int nTrim = 0;
+    for (int i = str.size()-1; (str[i] == '0' && isdigit(str[i-2])); --i)
+        ++nTrim;
+    if (nTrim)
+        str.erase(str.size()-nTrim, nTrim);
+
+    // Insert thousands-separators:
+    size_t point = str.find(".");
+    for (int i = (str.size()-point)+3; i < str.size(); i += 4)
         if (isdigit(str[str.size() - i - 1]))
             str.insert(str.size() - i, 1, ',');
     if (n < 0)
@@ -334,7 +348,7 @@
 bool ParseMoney(const char* pszIn, int64& nRet)
 {
     string strWhole;
-    int64 nCents = 0;
+    int64 nUnits = 0;
     const char* p = pszIn;
     while (isspace(*p))
         p++;
@@ -345,11 +359,11 @@
         if (*p == '.')
         {
             p++;
-            if (isdigit(*p))
+            int64 nMult = CENT*10;
+            while (isdigit(*p) && (nMult > 0))
             {
-                nCents = 10 * (*p++ - '0');
-                if (isdigit(*p))
-                    nCents += (*p++ - '0');
+                nUnits += nMult * (*p++ - '0');
+                nMult /= 10;
             }
             break;
         }
@@ -364,15 +378,11 @@
             return false;
     if (strWhole.size() > 14)
         return false;
-    if (nCents < 0 || nCents > 99)
+    if (nUnits < 0 || nUnits > COIN)
         return false;
     int64 nWhole = atoi64(strWhole);
-    int64 nPreValue = nWhole * 100 + nCents;
-    int64 nValue = nPreValue * CENT;
-    if (nValue / CENT != nPreValue)
-        return false;
-    if (nValue / COIN != nWhole)
-        return false;
+    int64 nValue = nWhole*COIN + nUnits;
+
     nRet = nValue;
     return true;
 }