Преобразование восьмеричной в десятичную точность Arbitray довольно раздражает, поскольку нет способа локализовать вычисления. Другими словами, изменение самой значимой цифры восьмеричного числа изменит даже самую младшую цифру в десятичном представлении.
Тем не менее, я думаю, что я бы преобразовал восьмеричное число в, скажем, число base-1000000000, а затем напечатал бы это (это вместо тривиальной проблемы, каждая цифра base-1000000000 просто отображается тривиально в 9 цифр base-10) .
Преобразование в base-1000000000 просто, потому что вам нужно только поддерживать увеличение и умножение на два (просто рассмотрите вход как двоичный с тремя битами для каждой восьмеричной цифры).
EDIT
Я пытался реализовать его на C ++, и вот код
#include <stdio.h>
#include <vector>
int main(int argc, const char *argv[]) {
// Base 100,000,000 accumulator
// Initialized with one digit = 0
std::vector<unsigned> big(1);
const unsigned DIGIT = 100000000;
for (int c=getchar(); c >= '0' && c <= '7'; c=getchar()) {
// Multiply accumulator by 8 and add in incoming digit
int carry = c - '0';
for (int i=0,n=big.size(); i<n; i++) {
unsigned x = big[i] * 8 + carry;
carry = x / DIGIT;
big[i] = x - carry * DIGIT;
}
if (carry) big.push_back(carry);
}
// Output result in decimal
printf("%i", big.back());
for (int i=int(big.size())-2; i>=0; i--) {
printf("%08i", big[i]);
}
putchar('\n');
return 0;
}
На моем ПК время преобразования восьмизначного восьмеричного числа в десятичное (в результате 72246 цифр) составляет около 1,2 секунды. Делая то же самое, используя python eval / str, время составляет около 3 секунд. Используемое число было "01234567" * 10000
.
Приведенный выше код использует 100 000 000 в качестве основы, чтобы он мог обрабатывать одну цифру (3 бита) за раз с 32-разрядной арифметикой, не переполняющейся промежуточными результатами. Я попытался также использовать 64-битные целые или 53-битную целую часть double
, но код выполнялся всегда медленнее, чем в этом случае (одна из причин, вероятно, - это деление во внутреннем цикле, которое можно преобразовать в умножение в 32 битовый регистр).
Это по-прежнему простая реализация O (n ^ 2), для преобразования которой в 10 000 000-значных восьмеричных чисел потребовались бы годы.