From f99804de08c64531ea6fcd508e1cf32ac237d0b2 Mon Sep 17 00:00:00 2001 From: Alexandre Paillier Date: Mon, 6 Jun 2022 18:36:20 +0200 Subject: [PATCH] Added a signed int256 formatting function --- src_common/uint128.c | 39 +++++++++++++++++++++++++++++++++++++++ src_common/uint128.h | 4 ++++ src_common/uint256.c | 39 +++++++++++++++++++++++++++++++++++++++ src_common/uint256.h | 5 +++++ 4 files changed, 87 insertions(+) diff --git a/src_common/uint128.c b/src_common/uint128.c index e286412..1962cc8 100644 --- a/src_common/uint128.c +++ b/src_common/uint128.c @@ -245,3 +245,42 @@ bool tostring128(const uint128_t *const number, reverseString(out, offset); return true; } + +/** + * Format a uint128_t into a string as a signed integer + * + * @param[in] number the number to format + * @param[in] base the radix used in formatting + * @param[out] out the output buffer + * @param[in] out_length the length of the output buffer + * @return whether the formatting was successful or not + */ +bool tostring128_signed(const uint128_t *const number, + uint32_t base, + char *const out, + uint32_t out_length) { + uint128_t max_unsigned_val; + uint128_t max_signed_val; + uint128_t one_val; + uint128_t two_val; + uint128_t tmp; + + // showing negative numbers only really makes sense in base 10 + if (base == 10) { + explicit_bzero(&one_val, sizeof(one_val)); + LOWER(one_val) = 1; + explicit_bzero(&two_val, sizeof(two_val)); + LOWER(two_val) = 2; + + memset(&max_unsigned_val, 0xFF, sizeof(max_unsigned_val)); + divmod128(&max_unsigned_val, &two_val, &max_signed_val, &tmp); + if (gt128(number, &max_signed_val)) // negative value + { + sub128(&max_unsigned_val, number, &tmp); + add128(&tmp, &one_val, &tmp); + out[0] = '-'; + return tostring128(&tmp, base, out + 1, out_length - 1); + } + } + return tostring128(number, base, out, out_length); // positive value +} diff --git a/src_common/uint128.h b/src_common/uint128.h index 8f76504..e1166c2 100644 --- a/src_common/uint128.h +++ b/src_common/uint128.h @@ -52,5 +52,9 @@ void divmod128(const uint128_t *const l, uint128_t *const div, uint128_t *const mod); bool tostring128(const uint128_t *const number, uint32_t base, char *const out, uint32_t outLength); +bool tostring128_signed(const uint128_t *const number, + uint32_t base, + char *const out, + uint32_t out_length); #endif // _UINT128_H_ diff --git a/src_common/uint256.c b/src_common/uint256.c index e8698ee..68ac0a3 100644 --- a/src_common/uint256.c +++ b/src_common/uint256.c @@ -248,3 +248,42 @@ bool tostring256(const uint256_t *const number, reverseString(out, offset); return true; } + +/** + * Format a uint256_t into a string as a signed integer + * + * @param[in] number the number to format + * @param[in] base the radix used in formatting + * @param[out] out the output buffer + * @param[in] out_length the length of the output buffer + * @return whether the formatting was successful or not + */ +bool tostring256_signed(const uint256_t *const number, + uint32_t base, + char *const out, + uint32_t out_length) { + uint256_t max_unsigned_val; + uint256_t max_signed_val; + uint256_t one_val; + uint256_t two_val; + uint256_t tmp; + + // showing negative numbers only really makes sense in base 10 + if (base == 10) { + explicit_bzero(&one_val, sizeof(one_val)); + LOWER(LOWER(one_val)) = 1; + explicit_bzero(&two_val, sizeof(two_val)); + LOWER(LOWER(two_val)) = 2; + + memset(&max_unsigned_val, 0xFF, sizeof(max_unsigned_val)); + divmod256(&max_unsigned_val, &two_val, &max_signed_val, &tmp); + if (gt256(number, &max_signed_val)) // negative value + { + sub256(&max_unsigned_val, number, &tmp); + add256(&tmp, &one_val, &tmp); + out[0] = '-'; + return tostring256(&tmp, base, out + 1, out_length - 1); + } + } + return tostring256(number, base, out, out_length); // positive value +} diff --git a/src_common/uint256.h b/src_common/uint256.h index dfc97f7..351953b 100644 --- a/src_common/uint256.h +++ b/src_common/uint256.h @@ -53,5 +53,10 @@ void divmod256(const uint256_t *const l, uint256_t *const div, uint256_t *const mod); bool tostring256(const uint256_t *const number, uint32_t base, char *const out, uint32_t outLength); +bool tostring256_signed(const uint256_t *const number, + uint32_t base, + char *const out, + uint32_t out_length); + #endif // _UINT256_H_