Чтобы представить любое число от 0 до 99999 с тремя цифрами, вам необходимо преобразовать число из основания 10 в более высокое основание b , где b 3 > 99999.
Наименьшее основание, соответствующее этому требованию, составляет 47. На выбор доступно 97 печатных символов ASCII, поэтому, очевидно, проблем нет.
Кстати, если вы конвертируетечисла в строки, которые будут видны пользователям, вы можете подумать о выборе символов, которые не имеют шансов на формирование неудачных строк, таких как bum
.
Следующий код должен работать.Он не оптимизирован, но должен быть достаточно быстрым, если вам не нужно конвертировать миллионы чисел в секунду.
#define ALPHABET "26789BCDFGHJKLMNPQRSTVWXYZbcdfghjklmnpqrstvwxyz"
#define LEN_ALPH 47
unsigned int asc2int(char *s) {
unsigned int i, result = 0;
while (*s) {
for (i=0; i<LEN_ALPH; i++) {
if (*s == ALPHABET[i]) break;
}
if (i == LEN_ALPH) return 0; /* Illegal character in input */
result = result * LEN_ALPH + i; /* TODO: Check for overflow */
s++;
}
return result;
}
char *int2asc(unsigned int n) {
static char result[7]; /* Should be sufficient for any 32-bit input */
char *ptr = result+6;
*ptr = '\0';
if (n == 0) {
*(--ptr) = ALPHABET[0];
}
else {
while (n) {
*(--ptr) = ALPHABET[n % LEN_ALPH];
n /= LEN_ALPH;
}
}
return ptr;
}
int main() {
unsigned int tests[10] = { 0, 1, 10, 100, 1000, 10000, 11111, 12345, 54321, 99999 };
unsigned int i, n;
char *s;
/* Test with selected numbers */
for (i=0; i<10; i++) {
s = int2asc(tests[i]);
n = asc2int(s);
printf("%u -> %s -> %u\n", tests[i], s, n);
}
/* Test all numbers */
for (i=0; i<100000; i++) {
if (asc2int(int2asc(i)) != i) {
printf("Failed at i=%u\n", i);
return 1;
}
}
return 0;
}