Преобразование числа из базы B1 в базу B2 без использования промежуточной базы

Есть ли способ преобразовать число из базы B1 в базу B2 без использования промежуточной базы.

Пример:

214 от основания 5 до базы 16 без преобразования его сначала в десятичную, а затем десятичную в шестнадцатеричную.

-

Спасибо

Алок Кр.

Ответы

Ответ 1

Чтобы преобразовать 214 base5 в базу 16 без промежуточной базы, вы просто должны знать, как вычислять непосредственно в базе 5.

Во-первых, вам нужна таблица того, что базовые 16 цифр находятся в базе 5 (вам нужна аналогичная таблица при преобразовании базы 10 в базовую 16, это просто то, что ее легче держать в голове!). Эту таблицу легко создать - просто начинайте с 0 и увеличивайте каждую базовую 5 строку до тех пор, пока не достигнете f в базе 16.

base 16 | base 5
--------+--------
      0 |  0
      1 |  1
      2 |  2
      3 |  3
      4 |  4
      5 | 10
      6 | 11
      7 | 12
      8 | 13
      9 | 14
      a | 20
      b | 21
      c | 22
      d | 23
      e | 24
      f | 30

Теперь вам просто нужно разделить на 16 (это 31 base5). Теперь мы вспоминаем наши дни начальной школы и используем длинное разделение (если это кажется трудным, потому что никто не заставил вас узнать ваши таблицы времени в базе 5!):

Шаг 1:

   ______
31 ) 214

Шаг 2:

       3 
   ______
31 ) 214 -
     143  

Шаг 3:

       3 
   _____
31 ) 214 -
     143  
    ----
      21

Таким образом, результат 214 base5, деленный на 31 base5, равен 3 base5 остаток 21 base5.

Это означает, что младшая значащая цифра в base16 равна 21 base5, которую вы можете найти в таблице: b base16. Результатом деления является 3 base5 - если это было больше 30 base5, тогда мы разделим снова - но это не так, поэтому это означает, что самая значимая цифра (используя таблица снова) 3 base16.

Итак, ответ: 214 base5= 3b base16.

Ответ 2

Это просто артефакт того, что мы используем десятичную систему. Поэтому вы хотите (в своей голове) подумать о "значении" каждого числа в десятичном значении. Таким образом, вы преобразовываете все обратно на базу 10. Если вы знали, как делать деление и умножение в других базах, было бы легко конвертировать туда и обратно без использования базы 10 в качестве промежуточного. Большинство людей, однако, обычно не делают базовое 5 деление/умножение и преобразуют все обратно в базовый 10.

Алгоритм один и тот же. Разделите на самую большую мощность новой базы, вы можете, а затем разделить остаток на меньшую мощность, и вы получите новую базу.

Например, от 0x3B до базы 5.

(математика находится в базе 16)

3B/5 ^ 2 = 2 остатка 9

9/5 = 1 остаток 4

поэтому 0x3B = 214 base 5

Если вы знаете, как делать деление без базового 10, это просто. Тем не менее, нет абсолютно никаких оснований для изучения этого, поэтому гораздо проще преобразовать обратно в базу 10 в качестве промежуточного шага.

Однако существует простой способ преобразования между двоичным и шестнадцатеричным. Просто разделите число на группы из 4 двоичных /1 шестнадцатеричных цифр и преобразуйте цифру по цифре.

1111 0000 1100 0001 
   F    0    9    1

Ответ 3

Не уверен, что вы имеете в виду. Числа на этих языках не находятся в базе 10 (если что-то, они основаны на 2) - при форматировании номера в строку вы отформатируете его с базой.

Итак, если у вас есть строковое представление числа, и вы конвертируете его в число, а затем отформатируете как другую базу - вы не конвертируете в базу 10 - вы преобразовываете строку в int в строку.

Итак, если вопрос заключается в том, как взять строку, которая представляет число в базе B1 и преобразовать ее в строку в базе B2 без преобразования ее в int, тогда я не вижу способ сделать это легко,

В вашем примере 214 в базе 5 есть 2*5^2 + 1 * 5 + 4 - но если вы не хотите конвертировать в int, то вы этого не знаете. Это число равно 59 в базе 10, но компьютер видит его как 00111011. Вы можете легко форматировать это как Hex. В конечном счете, вам нужно делать деления и размножаться в любом случае и где-то хранить промежуточные результаты.

Ответ 4

Я не верю, что существует какой-либо "синтаксический трюк", который позволяет сделать это для общего преобразования базы. (Трюк, который, например, позволяет перейти от строки "214" к строке "3B", не вычисляя, какое из целых чисел "214" (база 5) действительно соответствует.)

Под этим я подразумеваю, что вам обязательно нужно знать значение числа, с которым вы будете работать, т.е. вам нужно "разобрать" ввод.

214 в базе 5, например, анализируется как 2 * 5 2 + 1 * 5 + 4. Выполняя такое вычисление, вы не получите его в десятичной форме. Вы получите его в том, что когда-либо формирует ваш компьютер, решает сохранить полученное целое число в (возможно, двоичном:)

С этой точки вы можете легко выводить число в, например, основание 16. (Обратите внимание, что вы не прошли через базу 10.) Как сказал @Lou Franco, вы просто ушли из строки string > int- > string, вместо string- > string.

Ответ 5

Да и нет. Да, если вы не включаете тот факт, что компьютер делает все в двоичном виде (основание 2) в качестве другого представления. В конце концов, какова основа value в следующем коде?

long value = strtol(string, NULL, base);

В некоторых смыслах value является просто целым числом и не имеет связанной базы. Объедините это с функцией преобразования из значения в строковое представление в конкретной базе, и вы можете легко получить представление строки в одной базе до строкового представления в другой базе. Поскольку там нет промежуточного представления строки, есть какой-то смысл, нет промежуточного базового значения.

Ответ 6

Возможно, вы могли бы создать класс для представления каждой базы. Класс будет иметь ряд полей для представления каждой цифры - например, класс Decimal будет иметь поле единиц, поле десятков, поле сотен и так далее. Затем напишите мутаторы, чтобы добавить или вычесть один из значения, представленного объектом (и дескриптор переноса между полями), и аксессуар, который позволяет вам проверить, равно ли значение. Создайте объект в базе и со значением входного числа (возможно, напишите метод, который разбирает строку?), И объект в нужной базе с нулевым значением. Затем запустите цикл, в котором вы вычитаете один из входного номера и добавьте его к номеру вывода, пока номер входа не достигнет нуля.

Если вы создаете объекты, анализируя строки, вы можете избежать проблемы, о которой указывает aioobe, что вы представляете числа как двоичные, хотя вы, возможно, используете унарное представление. С небольшой мыслью вы также можете сделать базовый класс достаточно общим для обработки числа произвольных баз.

Ответ 7

Сохраните их как int, а затем конвертируйте, когда вам нужно их представлять, например std::ios_base.