1 // Copyright (c) 2009-2010 Satoshi Nakamoto 2 // Copyright (c) 2009-2020 The Bitcoin Core developers 3 // Distributed under the MIT software license, see the accompanying 4 // file COPYING or http://www.opensource.org/licenses/mit-license.php. 5 6 #include <util/moneystr.h> 7 8 #include <tinyformat.h> 9 #include <util/strencodings.h> 10 #include <util/string.h> 11 FormatMoney(const CAmount & n)12std::string FormatMoney(const CAmount& n) 13 { 14 // Note: not using straight sprintf here because we do NOT want 15 // localized number formatting. 16 int64_t n_abs = (n > 0 ? n : -n); 17 int64_t quotient = n_abs/COIN; 18 int64_t remainder = n_abs%COIN; 19 std::string str = strprintf("%d.%08d", quotient, remainder); 20 21 // Right-trim excess zeros before the decimal point: 22 int nTrim = 0; 23 for (int i = str.size()-1; (str[i] == '0' && IsDigit(str[i-2])); --i) 24 ++nTrim; 25 if (nTrim) 26 str.erase(str.size()-nTrim, nTrim); 27 28 if (n < 0) 29 str.insert((unsigned int)0, 1, '-'); 30 return str; 31 } 32 33 ParseMoney(const std::string & money_string,CAmount & nRet)34bool ParseMoney(const std::string& money_string, CAmount& nRet) 35 { 36 if (!ValidAsCString(money_string)) { 37 return false; 38 } 39 const std::string str = TrimString(money_string); 40 if (str.empty()) { 41 return false; 42 } 43 44 std::string strWhole; 45 int64_t nUnits = 0; 46 const char* p = str.c_str(); 47 for (; *p; p++) 48 { 49 if (*p == '.') 50 { 51 p++; 52 int64_t nMult = COIN / 10; 53 while (IsDigit(*p) && (nMult > 0)) 54 { 55 nUnits += nMult * (*p++ - '0'); 56 nMult /= 10; 57 } 58 break; 59 } 60 if (IsSpace(*p)) 61 return false; 62 if (!IsDigit(*p)) 63 return false; 64 strWhole.insert(strWhole.end(), *p); 65 } 66 if (*p) { 67 return false; 68 } 69 if (strWhole.size() > 10) // guard against 63 bit overflow 70 return false; 71 if (nUnits < 0 || nUnits > COIN) 72 return false; 73 int64_t nWhole = atoi64(strWhole); 74 CAmount nValue = nWhole*COIN + nUnits; 75 76 nRet = nValue; 77 return true; 78 } 79