Математика перетворення з будь-якої бази на будь-яку базу, не проходячи через базу 10?


36

Я розглядав математику, яка перетворюється з будь-якої бази на будь-яку базу. Це скоріше про підтвердження моїх результатів, ніж будь-що. Я знайшов свою відповідь на mathforum.org, але я все ще не впевнений, чи правильно я це маю. У мене перетворення з більшої бази на меншу базу вниз нормально, тому що це просто взяти першу цифру, помноживши на базу, ви хочете додати наступне повторення цифри. Моя проблема виникає при перетворенні з меншої бази на більшу базу. Роблячи це, вони говорять про те, як потрібно перетворити більшу базу, яку ви хочете, у меншу, яку ви маєте. Прикладом може бути перехід від бази 4 до бази 6, вам потрібно перетворити число 6 в базу 4, отримавши 12. Потім ви просто зробите те саме, що ви робили, перетворюючи велике в мале. Складність, з якою я маю це, мабуть, вам потрібно знати, що одне число знаходиться в іншій базі. Тож мені потрібно було б знати, що таке 6 в основі 4. Це створює велику проблему в моїй свідомості, тому що тоді мені знадобиться таблиця. Хтось знає спосіб зробити це кращим чином.

Я думав, що базове перетворення допоможе, але я не можу знайти цю роботу. І з сайту, який я знайшов, це, здається, дозволяє вам перетворити з бази на базу, не проходячи базову 10, але спочатку потрібно знати, як перетворити перше число з бази на базу. Це робить його свого роду безглуздим.

Коментатори кажуть, що мені потрібно вміти перетворювати лист у число. Якщо так, я вже це знаю. Однак це не моя проблема. Моя проблема полягає в тому, щоб перетворити велику базу на малу, мені потрібно спершу перетворити базове число, яке я маю, в базовий номер, який я хочу. Роблячи це, я перемагаю мету, тому що якщо я маю можливість перетворити ці бази на інші бази, я вже вирішив свою проблему.

Редагувати: я придумав, як перетворити з баз менше 10 рівних в інші бази, менші або рівні 10. Я також можу перейти з бази, що перевищує 10, до будь-якої бази, що становить 10 або менше. Проблема починається при перетворенні з бази більше 10 на іншу базу більше 10. Або перехід з бази менше 10 на базу більше 10. Мені не потрібен код Мені просто потрібна основна математика за ним, яка може бути застосовано до коду.


1
Це питання на тему цього форуму?
Андрій Бауер

2
Процедура тривіальна, якщо ви можете робити додавання та множення в цільовій базі. Якщо ви не можете, я не думаю, що це можливо.
Karolis Juodelė

9
Гріффіну слід спочатку сказати, що потрібно слухати багатьом учням: цифри існують без представлення в основі . Тоді відповідь зрозуміла: нам потрібні алгоритми, один для перетворення представлення числа в заданій базі в число (тобто те, що приймає a stringі повертає an int), і алгоритм, який приймає число і повертає його подання в заданій базі.
Андрій Бауер

1
@AndrejBauer Питання стосується CS: навіть якщо це не сформульовано таким чином, це питання про алгоритм перетворення між представленнями чисел. [Непов’язана примітка: я видалив купу заплутаних коментарів. Гриффін: відредагуйте своє запитання, щоб оновити його. Інші: будь ласка, поговоріть .]
Жил "ТАК - перестань бути злим"

1
@Griffin, минуло тривалий час з моменту вашого початкового запитання. Сподіваюся, ви знайшли свою відповідь. Якщо так, можливо, це може бути чудовою ідеєю оновити та прийняти відповідь чи опублікувати своє. Тим часом я знайшов пару дуже приємних ідей (про реалізацію в C ++) в Google Jam Code Archives. Деякі рішення цієї проблеми є дуже креативними code.google.com/codejam/contest/32003/dashboard
IsaacCisneros

Відповіді:


45

Це здається мені дуже основним питанням, тож вибачте, якщо я вас трохи прочитаю. Найважливішим моментом, який ви повинні дізнатися тут, є те, що число не є його цифрним поданням . Число є абстрактним математичним об'єктом, тоді як його цифрове зображення - це конкретна річ, а саме послідовність символів на папері (або послідовність бітів у обчислювальній пам'яті, або послідовність звуків, які ви видаєте під час передачі числа). Те, що вас бентежить, це те, що ви ніколи не бачите числа, а завжди його цифрного зображення. Отже, ви думаєте, що число - це представлення.

Отже, правильне запитання - це не "як перетворити з однієї бази в іншу", а "як я дізнаюся, яке число представлене заданим рядком цифр", а "як знайти цифрове представлення задане число ".

Тож давайте виробимо дві функції в Python, одну для перетворення цифрового представлення в число, а іншу для того, щоб робити зворотне. Примітка. Коли ми запускаємо функцію Python, звичайно, буде друкувати на екрані число, яке вона отримала в базі 10. Але це не означає, що комп'ютер зберігає цифри в базі 10 (це не так). Не має значення, як комп’ютер представляє числа.

def toDigits(n, b):
    """Convert a positive number n to its digit representation in base b."""
    digits = []
    while n > 0:
        digits.insert(0, n % b)
        n  = n // b
    return digits

def fromDigits(digits, b):
    """Compute the number given by digits in base b."""
    n = 0
    for d in digits:
        n = b * n + d
    return n

Спробуймо:

>>> toDigits(42, 2)
[1, 0, 1, 0, 1, 0]
>>> toDigits(42, 3)
[1, 1, 2, 0]
>>> fromDigits([1,1,2,0],3)
42

Озброївшись функціями перетворення, ваша проблема вирішується легко:

def convertBase(digits, b, c):
    """Convert the digits representation of a number from base b to base c."""
    return toDigits(fromDigits(digits, b), c)

Тест:

>>> convertBase([1,1,2,0], 3, 2) 
[1, 0, 1, 0, 1, 0]

Примітка: ми не пройшли представлення базової 10! Ми перетворили подання в число, а потім число в базу c . Число не було в жодному представництві. (Насправді це було так, комп'ютер повинен був якось представляти його, і він представляв його за допомогою електричних сигналів та фанк-штук, що відбувається в мікросхемах, але, безумовно, це були не 0-х та 1-х.)бc


4
Це не переконує мене на 100%. Насправді ви перетворили число в якесь представлення (хоча ви можете стверджувати, що не знаєте, що це таке), оскільки комп'ютери не є платонічними математиками, і ваш алгоритм не може перетворити довільну послідовність цифр у базі в базу b 2 ; він може конвертувати лише послідовності, представлені конкретною машиною. Пітон чарівно гнучкий; C не був би таким прощальним. Цілком справедливо запитати, як перетворити довільні рядки з b 1 в b 2 ; однак це можливо лише в лінійний час, за винятком певних базових комбінацій (наприклад, 2 <-> 16)b1b2b1b2
rici

1
Дійсно поставити запитання, але щоб знайти правильну відповідь, найкраще бути обізнаним про те, що числа є абстрактними сутностями.
Андрій Бауер

2
Це робить передати номер через підставу 10 подання, як fromDigitsповертається число в базі 10
apnorton

8
@anorton: Ні, напевне, це не так . Python друкує число на екрані в базовому 10-значному поданні, але саме число таким чином не зберігається. Те, що я намагаюсь зіткнутися, це те, що не має значення, як номери реалізовані всередині Python. Не важливо. Важливо лише те, що вони поводяться як числа.
Андрій Бауер

3
Нарешті, загальне рішення для будь-якої бази та не обмежується конкретними випадками використання, основами менше 36 або випадками, коли ви можете знайти достатньо унікальних символів.
Дж. Моні

21

Я думаю, що найкращий спосіб зрозуміти це - це обговорення з іноземцем (принаймні, як аналогія).

Визначення - це число в базі bхб означає, що - рядок цифр < b .х<б

Приклади Рядок цифр 10010011011 - це число в базі 2, рядок 68416841531 - це число в базі 10, BADCAFE - число в базі 16.

Тепер припустимо, що я виріс на планеті QUUX, де всіх навчають працювати в протягом усього життя, і я зустрічаю вас, хто звик базувати b . Отже, ти покажи мені номер, і що я роблю? Мені потрібен спосіб його інтерпретувати:qб

Визначення Я можу інтерпретувати число в базі (Примітка: b - число в базі q ) за такою формулоюббq

[[ϵ]]=0[[с¯г]]=[[с¯]]×б+г

де позначає порожній рядок, а ˉ з d позначає рядок , що закінчується в значному д . Дивіться мій доказ того, що додаток додає до вступу до цієї нотації.ϵс¯гг

То що ж тут сталося? Ви дали мені число в базі і я інтерпретував це в базі q без будь-якої дивної філософії про те, що насправді є числами.бq

Ключове Ключове значення в цьому полягає в тому, що і + I - це функції, які працюють на базових q числах. Це прості алгоритми, визначені рекурсивно на базових числах q (рядки цифр).×+qq


Це може здатися трохи абстрактним, оскільки я використовую змінні, а не фактичні числа протягом усього часу. Отже, припустимо, що ви є базовою істотою 13 (використовуючи символи ), і я звик базувати 7 (що набагато розумніше), використовуючи символи α β γ δ ρ ρ ρ ξ .0123456789ХYZαβγδρζξ

Отже, я бачив ваш алфавіт і склав його так:

0α1β2γ3δ4ρ5ζ6ξ7βα8ββ9βγХβδYβρZβζ

βξ

60Z8

[[60Z8]]=ξ(βξ)3+α(βξ)2+βζ(βξ)+ββ

βζ×βξ

Квітна таблиця множення

×βγδρζξββγδρζξγγρξβββδβζδδξβγβζγβγρρρβββζγγγξδδζζβδγβγξδρργξξβζγρδδργζββαβαγαδαραζαξα

βζ×βξ

βζ×βξξγρβζδβγγ

тож у мене це далеко

[[60Z8]]=ξ(βξ)3+α(βξ)2+βζ(βξ)+ββ=ξ(βξ)3+α(βξ)2+δβγ+ββ

Тепер мені потрібно виконати додавання за допомогою алгоритму, про який було сказано раніше:

δβγββδγδ

так

[[60Z8]]=ξ(βξ)3+α(βξ)2+βζ(βξ)+ββ=ξ(βξ)3+α(βξ)2+δβγ+ββ=ξ(βξ)3+α(βξ)2+δγδ

[[60Z8]]=ζδξγρ.

qбq


1
Добре, що це було багато чітких ліній. Як я можу змусити комп’ютер це зробити?
Гриффін

1
@Griffin, я думаю, ти задаєш це (дивне) запитання передчасно. Ви вибираєте мову програмування та вводите алгоритм додавання та множення на базові числа q (представлені у вигляді списків цифр), потім визначаєте функцію інтерпретації базових цифр b у базові числа q та інтерпретацію базових b чисел у базові q числа. Я все це пояснив.

Справа в тому, що я знаю концепцію, яку ви намагаєтеся зобразити. Моя проблема в тому, що мій комп'ютер не може використовувати ваші чіткі лінії.
Гриффін

Я знаю, що ви пояснили, але реалізувати це набагато складніше. Ви бачите, що визначити ці цифри не так просто.
Гриффін

1
Крім того, чому ви скинули альфа-цифру в найбільш значущу позицію? Оскільки 6 = & xi ;, не було б 7 = & alpha; & alpha ;?
Джованні Ботта

9

Це лише рефакторинг (Python 3) коду Андрія . У кодах Андрія номери представлені через перелік цифр (скалярів), тоді як у наступних кодових числах представлено список списків символів, узятих із користувацького рядка :

def v2r(n, base): # value to representation
    """Convert a positive number to its digit representation in a custom base."""
    b = len(base)
    digits = ''
    while n > 0:
        digits = base[n % b] + digits
        n  = n // b
    return digits

def r2v(digits, base): # representation to value
    """Compute the number represented by string 'digits' in a custom base."""
    b = len(base)
    n = 0
    for d in digits:
        n = b * n + base[:b].index(d)
    return n

def b2b(digits, base1, base2):
    """Convert the digits representation of a number from base1 to base2."""
    return v2r(r2v(digits, base1), base2)

Щоб здійснити перетворення від значення до представлення у спеціальній базі:

>>> v2r(64,'01')
'1000000'
>>> v2r(64,'XY')
'YXXXXXX'
>>> v2r(12340,'ZABCDEFGHI') # decimal base with custom symbols
'ABCDZ'

Щоб здійснити перетворення від представлення (у користувацькій базі) до значення:

>>> r2v('100','01')
4
>>> r2v('100','0123456789') # standard decimal base
100
>>> r2v('100','01_whatevr') # decimal base with custom symbols
100
>>> r2v('100','0123456789ABCDEF') # standard hexadecimal base
256
>>> r2v('100','01_whatevr-jklmn') # hexadecimal base with custom symbols
256

Для здійснення перетворення бази з однієї бази даних на інший:

>>> b2b('1120','012','01')
'101010'
>>> b2b('100','01','0123456789')
'4'
>>> b2b('100','0123456789ABCDEF','01')
'100000000'

1
Ласкаво просимо на сайт і дякуємо за ваш внесок. Однак створення оптимізованого вихідного коду - це не те, що насправді цей сайт. Код Андрія робить поняття зрозумілими, це те, що потрібно для його відповіді, але вдосконалення коду - це питання не програмування, а не інформатики .
Девід Річербі

1
@DavidRicherby Я частково погоджуюся, але цей внесок був занадто довгим для коментарів, і найкраще його місце було десь поруч з відповіддю Андрія, тому я розмістив його тут. У будь-якому випадку, якщо ви вважаєте, що краще, я міг би перетворити його на коментар із посиланням на код, але чи не буде це надлишком пуризму?
mmj

1

Фундаментальна операція перетворення бази - це toDigits()операція відповіді @AndrejBauer. Однак для цього немає необхідності створювати число у внутрішньому представленні чисел, що в основному є перетворенням з представлення 2 та базовим. Ви можете зробити необхідні операції в оригінальному базовому поданні.

Отже, перший крок - зробити повторювану операцію поділу модуля

def convertBase(n,original_base,destination_base):
    digits = []    
    while not is_zero(n):
        digits.insert(0,modulo_div(n,original_base,destination_base))
    return digits

Оскільки внутрішнє представлення - це цифри, потрібно зробити спеціалізовану функцію для тестування нуля

def is_zero(n):
    for d in n:
        if d != 0:
            return False
    return True

Врешті-решт треба зробити операцію modulo_div, яка насправді є стандартним поділом за базовим призначенням, як ми дізналися в школі.

def modulo_div(n,original_base,destination_base):
    carry = 0
    for i in range(len(n)):
        d = n[i]
        d+=original_base*carry 
        carry = d%destination_base 
        d=(d//destination_base)
        n[i] = d
        #print(i,d,carry)
    return carry

просто перевірка перевірки правильності коду:

print(convertBase([1,1,2,0], 3, 2))
#[1, 0, 1, 0, 1, 0]

print(convertBase([1, 0, 1, 0, 1, 0], 2, 3))
#[1, 1, 2, 0]

Дякуємо за публікацію, але зауважте, що ми не кодуємо сайт, тому великий блок коду не підходить як відповідь тут. Особливо, коли питання прямо говорить: "Мені не потрібен код, мені просто потрібна основна математика".
Девід Річербі

@DavidRicherby Я намагався додати текст.
Xavier Combelle

Спасибі. І я бачу, що на цій сторінці є чорт з великим кодом, незважаючи на те, що я сказав!
Девід Річербі

0

Я знаю простий спосіб здійснити конвертацію бази, який не вимагає комп'ютерної програми. Це шляхом визначення способу перетворення з будь-якої бази в базу 2 і навпаки, а потім покриття з однієї бази в іншу, спочатку перетворення з першої бази в базу 2, а потім перетворення з бази 2 в іншу. 2 так просто множити або ділити на будь-яку базу.

Щоб перетворити з будь-якої бази в базу 2, все, що вам потрібно зробити, це визнати, що для будь-якого числа, якщо ви берете його позначення бази 2 і починаєте з 0, а потім для кожної цифри в порядку зліва направо, подвійний, якщо ця цифра дорівнює нулю і подвійний, ніж додати 1, якщо ця цифра дорівнює 1, ви отримаєте саме це число. Враховуючи це число в будь-якій базі, ви можете ділити на 2 в цій базі, щоб отримати коефіцієнт і залишок. Якщо залишок дорівнює 1, остання двійкова цифра дорівнює 1, а залишок - 0, остання двійкова цифра - 0. Знову поділіться на 2. Якщо залишок дорівнює 1, друга остання цифра дорівнює 1, а решта - 0, друга остання цифра дорівнює 0 і так далі, поки не отримаєте коефіцієнт 0.

Щоб перетворити з бази 2 в будь-яку базу, все, що вам потрібно зробити, - це в цій базі, почніть з 0, а потім для кожної двійкової цифри, що йде зліва направо, двічі в цій базі, якщо ця цифра дорівнює 0, і подвійне, а потім додайте 1 у цьому базовий, якщо ця цифра дорівнює 1.


2 is so easy to multiply or divide by in any base. Я не бачу цього для непарних баз, які більше однієї з будь-якої потужності двох (для початку 11 і 13).
сіра борода

0

Ви можете конвертувати з бази n до бази 10 без будь-якого перетворення на якусь проміжну базу.

Наприклад, для перетворення з бази n в базу 9, ви берете алгоритм перетворення в базу 10 і замінюєте "10" на "9". Те саме для будь-якої іншої бази.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.