From 83b9f4279644d570a9d4629f23ef2f6e413167db Mon Sep 17 00:00:00 2001 From: Gavin Andresen Date: Wed, 23 Feb 2011 14:24:16 -0500 Subject: [PATCH 1/5] Use ValueFromAmount consistently --- rpc.cpp | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/rpc.cpp b/rpc.cpp index 40013809..ae1968d4 100644 --- a/rpc.cpp +++ b/rpc.cpp @@ -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); } From 789259d2e72f28330dbe70e8acfdf752bd950b76 Mon Sep 17 00:00:00 2001 From: Gavin Andresen Date: Wed, 23 Feb 2011 14:41:19 -0500 Subject: [PATCH 2/5] Do not round input amounts; allow RPC full precision. --- rpc.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rpc.cpp b/rpc.cpp index ae1968d4..1c6f228e 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; From 87504abb070cf9df4b2bf24787ce14643df9b07d Mon Sep 17 00:00:00 2001 From: Gavin Andresen Date: Wed, 23 Feb 2011 16:01:17 -0500 Subject: [PATCH 3/5] FormatMoney: show full-precision values --- util.cpp | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/util.cpp b/util.cpp index 94b0242d..5f6f10a3 100644 --- a/util.cpp +++ b/util.cpp @@ -313,9 +313,18 @@ void ParseString(const string& str, char c, vector& 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) + string str = strprintf("%.08f", double(n > 0 ? n : -n)/double(COIN)); + + // 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) From b0ad55a08a32832709f3b298b588577422071a93 Mon Sep 17 00:00:00 2001 From: Gavin Andresen Date: Wed, 23 Feb 2011 16:26:15 -0500 Subject: [PATCH 4/5] ParseMoney: allow full precision --- util.cpp | 20 ++++++++------------ 1 file changed, 8 insertions(+), 12 deletions(-) diff --git a/util.cpp b/util.cpp index 5f6f10a3..8518e279 100644 --- a/util.cpp +++ b/util.cpp @@ -343,7 +343,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++; @@ -354,11 +354,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; } @@ -373,15 +373,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; } From 8a9cad44a57f1e0057c127ced5078d7e722b9cc8 Mon Sep 17 00:00:00 2001 From: Gavin Andresen Date: Mon, 28 Feb 2011 21:34:36 +0000 Subject: [PATCH 5/5] Avoid sprintf decimal-point localization --- util.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/util.cpp b/util.cpp index 8518e279..8a2f9d52 100644 --- a/util.cpp +++ b/util.cpp @@ -313,7 +313,12 @@ void ParseString(const string& str, char c, vector& v) string FormatMoney(int64 n, bool fPlus) { - string str = strprintf("%.08f", double(n > 0 ? n : -n)/double(COIN)); + // 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;