diff options
author | Damien George <damien.p.george@gmail.com> | 2014-04-07 21:50:22 +0100 |
---|---|---|
committer | Damien George <damien.p.george@gmail.com> | 2014-04-07 21:50:22 +0100 |
commit | 97543c5285b47c765e19d6ab7c08b36630e23c6a (patch) | |
tree | fd55f309f8eaa4059dd7e4160250c22f115d2b59 /py/mpz.c | |
parent | 98dd6d7712acdefb9179743564ee546339da9519 (diff) | |
parent | 23dc6d0aceba51756f01e96c099678c38b4a88f9 (diff) | |
download | micropython-97543c5285b47c765e19d6ab7c08b36630e23c6a.tar.gz micropython-97543c5285b47c765e19d6ab7c08b36630e23c6a.zip |
Merge pull request #447 from dhylands/str-format-mpz
Add string formatting support for longlong and mpz.
Diffstat (limited to 'py/mpz.c')
-rw-r--r-- | py/mpz.c | 46 |
1 files changed, 37 insertions, 9 deletions
@@ -1216,15 +1216,27 @@ uint mpz_as_str_size(const mpz_t *i, uint base) { return i->len * DIG_SIZE / log_base2_floor[base] + 2 + 1; // +1 for null byte termination } +uint mpz_as_str_size_formatted(const mpz_t *i, uint base, const char *prefix, char comma) { + if (base < 2 || base > 32) { + return 0; + } + + uint num_digits = i->len * DIG_SIZE / log_base2_floor[base] + 1; + uint num_commas = comma ? num_digits / 3: 0; + uint prefix_len = prefix ? strlen(prefix) : 0; + + return num_digits + num_commas + prefix_len + 2; // +1 for sign, +1 for null byte +} + char *mpz_as_str(const mpz_t *i, uint base) { char *s = m_new(char, mpz_as_str_size(i, base)); - mpz_as_str_inpl(i, base, s); + mpz_as_str_inpl(i, base, "", 'a', 0, s); return s; } // assumes enough space as calculated by mpz_as_str_size // returns length of string, not including null byte -uint mpz_as_str_inpl(const mpz_t *i, uint base, char *str) { +uint mpz_as_str_inpl(const mpz_t *i, uint base, const char *prefix, char base_char, char comma, char *str) { if (str == NULL || base < 2 || base > 32) { str[0] = 0; return 0; @@ -1232,10 +1244,15 @@ uint mpz_as_str_inpl(const mpz_t *i, uint base, char *str) { uint ilen = i->len; + char *s = str; if (ilen == 0) { - str[0] = '0'; - str[1] = 0; - return 1; + if (prefix) { + while (*prefix) + *s++ = *prefix++; + } + *s++ = '0'; + *s = '\0'; + return s - str; } // make a copy of mpz digits @@ -1243,7 +1260,7 @@ uint mpz_as_str_inpl(const mpz_t *i, uint base, char *str) { memcpy(dig, i->dig, ilen * sizeof(mpz_dig_t)); // convert - char *s = str; + char *last_comma = str; bool done; do { mpz_dig_t *d = dig + ilen; @@ -1259,7 +1276,7 @@ uint mpz_as_str_inpl(const mpz_t *i, uint base, char *str) { // convert to character a += '0'; if (a > '9') { - a += 'a' - '9' - 1; + a += base_char - '9' - 1; } *s++ = a; @@ -1271,8 +1288,19 @@ uint mpz_as_str_inpl(const mpz_t *i, uint base, char *str) { break; } } - } while (!done); + if (comma && (s - last_comma) == 3) { + *s++ = comma; + last_comma = s; + } + } + while (!done); + if (prefix) { + const char *p = &prefix[strlen(prefix)]; + while (p > prefix) { + *s++ = *--p; + } + } if (i->neg != 0) { *s++ = '-'; } @@ -1284,7 +1312,7 @@ uint mpz_as_str_inpl(const mpz_t *i, uint base, char *str) { *v = temp; } - s[0] = 0; // null termination + *s = '\0'; // null termination return s - str; } |