aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGavin Andresen <gavinandresen@gmail.com>2011-03-02 15:03:49 -0500
committerGavin Andresen <gavinandresen@gmail.com>2011-03-02 15:03:49 -0500
commit411493b1f70d1493b1203bce847baa9f41e79f91 (patch)
treea1873a7b2361fbeaeab35339a5298a01c72aae90
parent6665aca02421e62c194dd8291b4ab7c91eea72c7 (diff)
parent8a9cad44a57f1e0057c127ced5078d7e722b9cc8 (diff)
downloadbitcoin-411493b1f70d1493b1203bce847baa9f41e79f91.tar.xz
Merge branch 'rounding'
-rw-r--r--rpc.cpp18
-rw-r--r--util.cpp40
2 files changed, 34 insertions, 24 deletions
diff --git a/rpc.cpp b/rpc.cpp
index 4001380987..1c6f228e5b 100644
--- a/rpc.cpp
+++ b/rpc.cpp
@@ -65,7 +65,7 @@ int64 AmountFromValue(const Value& value)
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 @@ Value getinfo(const Array& params, bool fHelp)
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 @@ Value getinfo(const Array& params, bool fHelp)
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 @@ Value getreceivedbyaddress(const Array& params, bool fHelp)
}
}
- return (double)nAmount / (double)COIN;
+ return ValueFromAmount(nAmount);
}
@@ -619,7 +619,7 @@ Value getbalance(const Array& params, bool fHelp)
"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 @@ Value getbalance(const Array& params, bool fHelp)
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 @@ Value getbalance(const Array& params, bool fHelp)
int64 nBalance = GetAccountBalance(strAccount, nMinDepth);
- return (double)nBalance / (double)COIN;
+ return ValueFromAmount(nBalance);
}
@@ -851,7 +851,7 @@ Value ListReceived(const Array& params, bool fByAccounts)
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 @@ Value ListReceived(const Array& params, bool fByAccounts)
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);
}
diff --git a/util.cpp b/util.cpp
index 94b0242dc7..8a2f9d525e 100644
--- a/util.cpp
+++ b/util.cpp
@@ -313,9 +313,23 @@ void ParseString(const string& str, char c, vector<string>& v)
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 string& str, int64& nRet)
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 @@ bool ParseMoney(const char* pszIn, int64& nRet)
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 @@ bool ParseMoney(const char* pszIn, int64& nRet)
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;
}