/* itoa.c Copyleft (C) 2022 Taiji Yamada */ #include #include #include char *itoa(int v, char *b, const int r) { const char digits[] = "0123456789abcdefghijklmnopqrstuv"; b[0] = '\0'; if (r == 8) snprintf(b, 256-1, "%o", v); else if (r == 10) snprintf(b, 256-1, "%d", v); else if (r == 16) snprintf(b, 256-1, "%x", v); else { const unsigned long long radix = (unsigned long long)r; const int sign = (r == 10 && v < 0) ? -1 : 1; unsigned long long value = (r == 10 && v < 0) ? (unsigned int)-v : (unsigned int)v; unsigned long long ub = 1, previous_ub = ub; while (!0) { ub *= radix; if (ub < previous_ub) break; if (value < ub) break; previous_ub = ub; } ub = previous_ub; if (sign == -1) strcat(b, "-"); while (0 < ub) { const unsigned long long n = value / ub; char s[] = { digits[n], '\0' }; strcat(b, s); value -= n*ub; ub /= radix; } } return b; } int stoi(const char *b, const int r) { const char digits[] = "0123456789abcdefghijklmnopqrstuv"; const unsigned long long radix = (unsigned long long)r; const size_t l = strlen(b); int sign = 1; unsigned long long e = 1, value = 0; for (size_t i=l-1; ; --i) { const unsigned long long n = strchr(digits, b[i]) - digits; value += e*n; if (i == 0) break; if (b[i-1] == '-') { sign = -1; break; } e *= radix; } return (sign != -1) ? (int)value : -(int)value; } char *i16toa(int16_t v, char *b, const int r) { const char digits[] = "0123456789abcdefghijklmnopqrstuv"; b[0] = '\0'; if (r == 8) snprintf(b, 256-1, "%" PRIo16, v); else if (r == 10) snprintf(b, 256-1, "%" PRId16, v); else if (r == 16) snprintf(b, 256-1, "%" PRIx16, v); else { const unsigned long long radix = (unsigned long long)r; const int sign = (r == 10 && v < 0) ? -1 : 1; unsigned long long value = (r == 10 && v < 0) ? (uint16_t)-v : (uint16_t)v; unsigned long long ub = 1, previous_ub = ub; while (!0) { ub *= radix; if (ub < previous_ub) break; if (value < ub) break; previous_ub = ub; } ub = previous_ub; if (sign == -1) strcat(b, "-"); while (0 < ub) { const unsigned long long n = value / ub; char s[] = { digits[n], '\0' }; strcat(b, s); value -= n*ub; ub /= radix; } } return b; } int16_t stoi16(const char *b, const int r) { const char digits[] = "0123456789abcdefghijklmnopqrstuv"; const unsigned long long radix = (unsigned long long)r; const size_t l = strlen(b); int sign = 1; unsigned long long e = 1, value = 0; for (size_t i=l-1; ; --i) { const unsigned long long n = strchr(digits, b[i]) - digits; value += e*n; if (i == 0) break; if (b[i-1] == '-') { sign = -1; break; } e *= radix; } return (sign != -1) ? (int16_t)value : -(int16_t)value; } char *ui16toa(uint16_t v, char *b, const int r) { const char digits[] = "0123456789abcdefghijklmnopqrstuv"; b[0] = '\0'; if (r == 8) snprintf(b, 256-1, "%" PRIo16, v); else if (r == 10) snprintf(b, 256-1, "%" PRIu16, v); else if (r == 16) snprintf(b, 256-1, "%" PRIx16, v); else { const unsigned long long radix = (unsigned long long)r; unsigned long long value = v; unsigned long long ub = 1, previous_ub = ub; while (!0) { ub *= radix; if (ub < previous_ub) break; if (value < ub) break; previous_ub = ub; } ub = previous_ub; while (0 < ub) { const unsigned long long n = value / ub; char s[] = { digits[n], '\0' }; strcat(b, s); value -= n*ub; ub /= radix; } } return b; } int16_t stoui16(const char *b, const int r) { const char digits[] = "0123456789abcdefghijklmnopqrstuv"; const unsigned long long radix = (unsigned long long)r; const size_t l = strlen(b); int sign = 1; unsigned long long e = 1, value = 0; for (size_t i=l-1; ; --i) { const unsigned long long n = strchr(digits, b[i]) - digits; value += e*n; if (i == 0) break; if (b[i-1] == '-') { sign = -1; break; } e *= radix; } return (sign != -1) ? (uint16_t)value : -(uint16_t)value; } char *i32toa(int32_t v, char *b, const int r) { const char digits[] = "0123456789abcdefghijklmnopqrstuv"; b[0] = '\0'; if (r == 8) snprintf(b, 256-1, "%" PRIo32, v); else if (r == 10) snprintf(b, 256-1, "%" PRId32, v); else if (r == 16) snprintf(b, 256-1, "%" PRIx32, v); else { const unsigned long long radix = (unsigned long long)r; const int sign = (r == 10 && v < 0) ? -1 : 1; unsigned long long value = (r == 10 && v < 0) ? (uint32_t)-v : (uint32_t)v; unsigned long long ub = 1, previous_ub = ub; while (!0) { ub *= radix; if (ub < previous_ub) break; if (value < ub) break; previous_ub = ub; } ub = previous_ub; if (sign == -1) strcat(b, "-"); while (0 < ub) { const unsigned long long n = value / ub; char s[] = { digits[n], '\0' }; strcat(b, s); value -= n*ub; ub /= radix; } } return b; } int32_t stoi32(const char *b, const int r) { const char digits[] = "0123456789abcdefghijklmnopqrstuv"; const unsigned long long radix = (unsigned long long)r; const size_t l = strlen(b); int sign = 1; unsigned long long e = 1, value = 0; for (size_t i=l-1; ; --i) { const unsigned long long n = strchr(digits, b[i]) - digits; value += e*n; if (i == 0) break; if (b[i-1] == '-') { sign = -1; break; } e *= radix; } return (sign != -1) ? (int32_t)value : -(int32_t)value; } char *ui32toa(uint32_t v, char *b, const int r) { const char digits[] = "0123456789abcdefghijklmnopqrstuv"; b[0] = '\0'; if (r == 8) snprintf(b, 256-1, "%" PRIo32, v); else if (r == 10) snprintf(b, 256-1, "%" PRIu32, v); else if (r == 16) snprintf(b, 256-1, "%" PRIx32, v); else { const unsigned long long radix = (unsigned long long)r; unsigned long long value = v; unsigned long long ub = 1, previous_ub = ub; while (!0) { ub *= radix; if (ub < previous_ub) break; if (value < ub) break; previous_ub = ub; } ub = previous_ub; while (0 < ub) { const unsigned long long n = value / ub; char s[] = { digits[n], '\0' }; strcat(b, s); value -= n*ub; ub /= radix; } } return b; } uint32_t stoui32(const char *b, const int r) { const char digits[] = "0123456789abcdefghijklmnopqrstuv"; const unsigned long long radix = (unsigned long long)r; const size_t l = strlen(b); int sign = 1; unsigned long long e = 1, value = 0; for (size_t i=l-1; ; --i) { const unsigned long long n = strchr(digits, b[i]) - digits; value += e*n; if (i == 0) break; if (b[i-1] == '-') { sign = -1; break; } e *= radix; } return (sign != -1) ? (uint32_t)value : -(uint32_t)value; }