Преобразование числа из базы 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
.