diff options
| author | luigi1111 <luigi1111w@gmail.com> | 2022-04-18 02:12:55 -0500 |
|---|---|---|
| committer | luigi1111 <luigi1111w@gmail.com> | 2022-04-18 02:12:55 -0500 |
| commit | 2b999f5398426d2c4452e001cfebad34abb686ff (patch) | |
| tree | 08bbe9298a72bd99ca3e35d3df667d81ef07711e /src/cryptonote_basic/cryptonote_format_utils.cpp | |
| parent | f49fc9b4876382d5c6f08fd7a6125b554c49e260 (diff) | |
| parent | b030f207517f59a5122409398549a02ac23829ae (diff) | |
| download | monzero-core-2b999f5398426d2c4452e001cfebad34abb686ff.tar.gz monzero-core-2b999f5398426d2c4452e001cfebad34abb686ff.tar.xz monzero-core-2b999f5398426d2c4452e001cfebad34abb686ff.zip | |
Merge pull request #7819
b030f20 Fee changes from ArticMine (moneromooo-monero)
9f786f0 epee: allow copying a rolling_median_t object (moneromooo-monero)
Diffstat (limited to 'src/cryptonote_basic/cryptonote_format_utils.cpp')
| -rw-r--r-- | src/cryptonote_basic/cryptonote_format_utils.cpp | 63 |
1 files changed, 63 insertions, 0 deletions
diff --git a/src/cryptonote_basic/cryptonote_format_utils.cpp b/src/cryptonote_basic/cryptonote_format_utils.cpp index 1bc6b6377..d8f9bb176 100644 --- a/src/cryptonote_basic/cryptonote_format_utils.cpp +++ b/src/cryptonote_basic/cryptonote_format_utils.cpp @@ -1064,6 +1064,69 @@ namespace cryptonote return s; } //--------------------------------------------------------------- + uint64_t round_money_up(uint64_t amount, unsigned significant_digits) + { + // round monetary amount up with the requested amount of significant digits + + CHECK_AND_ASSERT_THROW_MES(significant_digits > 0, "significant_digits must not be 0"); + static_assert(sizeof(unsigned long long) == sizeof(uint64_t), "Unexpected unsigned long long size"); + + // we don't need speed, so we do it via text, as it's easier to get right + char buf[32]; + snprintf(buf, sizeof(buf), "%llu", (unsigned long long)amount); + const size_t len = strlen(buf); + if (len > significant_digits) + { + bool bump = false; + char *ptr; + for (ptr = buf + significant_digits; *ptr; ++ptr) + { + // bump digits by one if the following digits past significant digits were to be 5 or more + if (*ptr != '0') + { + bump = true; + *ptr = '0'; + } + } + ptr = buf + significant_digits; + while (bump && ptr > buf) + { + --ptr; + // bumping a nine overflows + if (*ptr == '9') + *ptr = '0'; + else + { + // bumping another digit means we can stop bumping (no carry) + ++*ptr; + bump = false; + } + } + if (bump) + { + // carry reached the highest digit, we need to add a 1 in front + size_t offset = strlen(buf); + for (size_t i = offset + 1; i > 0; --i) + buf[i] = buf[i - 1]; + buf[0] = '1'; + } + } + char *end = NULL; + errno = 0; + const unsigned long long ull = strtoull(buf, &end, 10); + CHECK_AND_ASSERT_THROW_MES(ull != ULONG_MAX || errno == 0, "Failed to parse rounded amount: " << buf); + CHECK_AND_ASSERT_THROW_MES(ull != 0 || amount == 0, "Overflow in rounding"); + return ull; + } + //--------------------------------------------------------------- + std::string round_money_up(const std::string &s, unsigned significant_digits) + { + uint64_t amount; + CHECK_AND_ASSERT_THROW_MES(parse_amount(amount, s), "Failed to parse amount: " << s); + amount = round_money_up(amount, significant_digits); + return print_money(amount); + } + //--------------------------------------------------------------- crypto::hash get_blob_hash(const blobdata& blob) { crypto::hash h = null_hash; |
