Merge branch 'rounding'

This commit is contained in:
Gavin Andresen 2011-03-02 15:03:49 -05:00
commit 411493b1f7
2 changed files with 34 additions and 24 deletions

18
rpc.cpp
View file

@ -65,7 +65,7 @@ int64 AmountFromValue(const Value& value)
double dAmount = value.get_real(); double dAmount = value.get_real();
if (dAmount <= 0.0 || dAmount > 21000000.0) if (dAmount <= 0.0 || dAmount > 21000000.0)
throw JSONRPCError(-3, "Invalid amount"); throw JSONRPCError(-3, "Invalid amount");
int64 nAmount = roundint64(dAmount * 100.00) * CENT; int64 nAmount = roundint64(dAmount * COIN);
if (!MoneyRange(nAmount)) if (!MoneyRange(nAmount))
throw JSONRPCError(-3, "Invalid amount"); throw JSONRPCError(-3, "Invalid amount");
return nAmount; return nAmount;
@ -277,7 +277,7 @@ Value getinfo(const Array& params, bool fHelp)
Object obj; Object obj;
obj.push_back(Pair("version", (int)VERSION)); 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("blocks", (int)nBestHeight));
obj.push_back(Pair("connections", (int)vNodes.size())); obj.push_back(Pair("connections", (int)vNodes.size()));
obj.push_back(Pair("proxy", (fUseProxy ? addrProxy.ToStringIPPort() : string()))); 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("hashespersec", gethashespersec(params, false)));
obj.push_back(Pair("testnet", fTestNet)); obj.push_back(Pair("testnet", fTestNet));
obj.push_back(Pair("keypoololdest", (boost::int64_t)GetOldestKeyPoolTime())); 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"))); obj.push_back(Pair("errors", GetWarnings("statusbar")));
return obj; 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 [account] is specified, returns the balance in the account.");
if (params.size() == 0) if (params.size() == 0)
return ((double)GetBalance() / (double)COIN); return ValueFromAmount(GetBalance());
if (params[0].get_str() == "*") { if (params[0].get_str() == "*") {
// Calculate total balance a different way from GetBalance() // Calculate total balance a different way from GetBalance()
@ -648,7 +648,7 @@ Value getbalance(const Array& params, bool fHelp)
nBalance += allGenerated; nBalance += allGenerated;
} }
printf("Found %d accounts\n", vAccounts.size()); printf("Found %d accounts\n", vAccounts.size());
return (double)nBalance / (double)COIN; return ValueFromAmount(nBalance);
} }
string strAccount = AccountFromValue(params[0]); string strAccount = AccountFromValue(params[0]);
@ -658,7 +658,7 @@ Value getbalance(const Array& params, bool fHelp)
int64 nBalance = GetAccountBalance(strAccount, nMinDepth); 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("address", strAddress));
obj.push_back(Pair("account", strAccount)); obj.push_back(Pair("account", strAccount));
obj.push_back(Pair("label", strAccount)); // deprecated 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))); obj.push_back(Pair("confirmations", (nConf == INT_MAX ? 0 : nConf)));
ret.push_back(obj); ret.push_back(obj);
} }
@ -867,7 +867,7 @@ Value ListReceived(const Array& params, bool fByAccounts)
Object obj; Object obj;
obj.push_back(Pair("account", (*it).first)); obj.push_back(Pair("account", (*it).first));
obj.push_back(Pair("label", (*it).first)); // deprecated 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))); obj.push_back(Pair("confirmations", (nConf == INT_MAX ? 0 : nConf)));
ret.push_back(obj); ret.push_back(obj);
} }

View file

@ -313,9 +313,23 @@ void ParseString(const string& str, char c, vector<string>& v)
string FormatMoney(int64 n, bool fPlus) string FormatMoney(int64 n, bool fPlus)
{ {
n /= CENT; // Note: not using straight sprintf here because we do NOT want
string str = strprintf("%"PRI64d".%02"PRI64d, (n > 0 ? n : -n)/100, (n > 0 ? n : -n)%100); // localized number formatting.
for (int i = 6; i < str.size(); i += 4) 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])) if (isdigit(str[str.size() - i - 1]))
str.insert(str.size() - i, 1, ','); str.insert(str.size() - i, 1, ',');
if (n < 0) if (n < 0)
@ -334,7 +348,7 @@ bool ParseMoney(const string& str, int64& nRet)
bool ParseMoney(const char* pszIn, int64& nRet) bool ParseMoney(const char* pszIn, int64& nRet)
{ {
string strWhole; string strWhole;
int64 nCents = 0; int64 nUnits = 0;
const char* p = pszIn; const char* p = pszIn;
while (isspace(*p)) while (isspace(*p))
p++; p++;
@ -345,11 +359,11 @@ bool ParseMoney(const char* pszIn, int64& nRet)
if (*p == '.') if (*p == '.')
{ {
p++; p++;
if (isdigit(*p)) int64 nMult = CENT*10;
while (isdigit(*p) && (nMult > 0))
{ {
nCents = 10 * (*p++ - '0'); nUnits += nMult * (*p++ - '0');
if (isdigit(*p)) nMult /= 10;
nCents += (*p++ - '0');
} }
break; break;
} }
@ -364,15 +378,11 @@ bool ParseMoney(const char* pszIn, int64& nRet)
return false; return false;
if (strWhole.size() > 14) if (strWhole.size() > 14)
return false; return false;
if (nCents < 0 || nCents > 99) if (nUnits < 0 || nUnits > COIN)
return false; return false;
int64 nWhole = atoi64(strWhole); int64 nWhole = atoi64(strWhole);
int64 nPreValue = nWhole * 100 + nCents; int64 nValue = nWhole*COIN + nUnits;
int64 nValue = nPreValue * CENT;
if (nValue / CENT != nPreValue)
return false;
if (nValue / COIN != nWhole)
return false;
nRet = nValue; nRet = nValue;
return true; return true;
} }