FormatMoney(CAmount n)
is not being properly defined for n = std::numeric_limits<CAmount>::min()
. This is due to an invalid integer negation: the negation of -9223372036854775808
cannot be represented in type CAmount
(which has a max value of 9223372036854775807
):
FWIW FormatMoney(-9223372036854775808)
returns --92233720368.-54775808
when compiled with UBSan (LLVM/Clang, -fsanitize=undefined
).
Context: #20383 (review)
It would be nice if FormatMoney(CAmount n)
was properly defined for all CAmount n
:)
These are the “expectations of least surprise”:
0BOOST_CHECK_EQUAL(FormatMoney(std::numeric_limits<CAmount>::max()), "92233720368.54775807"); // 9223372036854775807
1BOOST_CHECK_EQUAL(FormatMoney(std::numeric_limits<CAmount>::max() - 1), "92233720368.54775806"); // 9223372036854775806
2BOOST_CHECK_EQUAL(FormatMoney(std::numeric_limits<CAmount>::max() - 2), "92233720368.54775805"); // 9223372036854775805
3BOOST_CHECK_EQUAL(FormatMoney(std::numeric_limits<CAmount>::max() - 3), "92233720368.54775804"); // 9223372036854775804
4BOOST_CHECK_EQUAL(FormatMoney(std::numeric_limits<CAmount>::min() + 3), "-92233720368.54775805"); // -9223372036854775805
5BOOST_CHECK_EQUAL(FormatMoney(std::numeric_limits<CAmount>::min() + 2), "-92233720368.54775806"); // -9223372036854775806
6BOOST_CHECK_EQUAL(FormatMoney(std::numeric_limits<CAmount>::min() + 1), "-92233720368.54775807"); // -9223372036854775807
7BOOST_CHECK_EQUAL(FormatMoney(std::numeric_limits<CAmount>::min()), "-92233720368.54775808"); // -9223372036854775808
These assertions are guaranteed to hold for all cases above except for the last one.