Matematica din spatele conversiei din orice bază în orice bază fără a trece prin baza 10?

Am analizat matematica din spatele conversiei de la orice bază la orice bază. Aceasta este mai mult despre confirmarea rezultatelor mele decât orice. Am găsit ceea ce pare să fii răspunsul meu pe mathforum.org, dar încă nu sunt sigur dacă am dreptate. Am conversia dintr-o bază mai mare într-o bază mai mică jos, pentru că este pur și simplu să luați prima cifră înmulțiți cu baza pe care doriți să o adăugați repetarea cifrei următoare. Problema mea vine la conversia de la o bază mai mică la o bază mai mare. Când fac acest lucru, ei vorbesc despre cum trebuie să convertiți baza mai mare pe care o doriți în baza mai mică pe care o aveți. Un exemplu ar fi să treceți de la baza 4 la baza 6, pentru a converti numărul 6 în baza 4 obținând 12. Apoi faceți același lucru ca și când ați făcut conversia de la mare la mic. Dificultatea pe care o am cu asta este că se pare că trebuie să știți care este un număr în cealaltă bază. Așadar, ar fi necesar să știu ce este 6 în baza 4. Acest lucru îmi creează o mare problemă în mintea mea, pentru că atunci aș avea nevoie de o masă. Știe cineva un mod de a face acest lucru într-un mod mai bun.

Am crezut că o conversie de bază ar ajuta, dar nu pot găsi niciun lucru care funcționează. Și de pe site-ul pe care l-am găsit pare să vă permită să faceți conversii de la bază la bază fără a trece prin baza 10, dar mai întâi trebuie să știu cum să convertească primul număr de la bază la bază. Asta îl face cam inutil.

Comentatorii spun că trebuie să pot converti o literă într-un număr. Dacă da, știu deja asta. Cu toate acestea, nu este problema mea. Problema mea este pentru a converti o bază mare într-o bază mică. Trebuie să convertesc mai întâi numărul de bază pe care îl am în numărul de bază dorit. Făcând acest lucru, am învins scopul, deoarece dacă am capacitatea de a converti aceste baze în alte baze, mi-am rezolvat deja problema.

Edit: Am descoperit cum să convertesc din baze mai mici sau egale. la 10 în alte baze mai mici sau egale cu 10. Pot, de asemenea, să trec de la o bază mai mare de 10 la orice bază care este 10 sau mai mică. Problema începe la conversia de la o bază mai mare de 10 la o altă bază mai mare de 10. Sau trecând de la o bază mai mică de 10 la o bază mai mare de 10. Nu am nevoie de cod, am nevoie doar de matematica de bază care poate fi aplicată codului.

Comentarii

  • Este această întrebare pe subiect pentru acest forum?
  • Procedura este banală atâta timp cât puteți face adunare și multiplicare în baza țintă. Dacă nu poți ‘ t, nu ‘ cred că este posibil ‘.
  • Griffin ar trebui mai întâi să spună ce trebuie să audă mulți studenți: numerele există fără a fi reprezentate într-o bază . Atunci răspunsul este clar: avem nevoie de algoritmi, unul pentru a converti o reprezentare a unui număr dintr-o bază dată la numărul (adică ceva care ia un string și returnează un int) și un algoritm care ia un număr și îi returnează reprezentarea într-o bază dată.
  • @AndrejBauer Întrebarea este despre CS : chiar dacă nu este ‘ formulat în acest fel, aceasta este o întrebare despre un algoritm de convertit între reprezentări numerice. [ Notă fără legătură: am șters o grămadă de comentarii confuze. Griffin: vă rugăm să editați întrebarea pentru a o actualiza. Altele: vă rugăm să îl duceți la chat . ]
  • @Griffin it a trecut mult timp de la întrebarea dvs. inițială. Sper că ‘ ți-ai găsit răspunsul. Dacă da, poate ar fi o idee excelentă să actualizați și să acceptați un răspuns sau să postați al dvs. Între timp, am ‘ găsit câteva idei foarte frumoase (vorbind despre implementarea în C ++) în Google ‘ s Code Jam Archives. Unele soluții pentru această problemă sunt foarte creative code.google.com/codejam/contest/32003/dashboard

Răspunde

Aceasta mi se pare o întrebare foarte de bază, așa că scuză-mă dacă te țin puțin. Cel mai important punct de învățat aici este că un număr nu este reprezentarea cifrelor sale . Un număr este un obiect matematic abstract, în timp ce reprezentarea cifrelor sale este un lucru concret, și anume o secvență de simboluri pe o hârtie (sau o secvență de biți în memoria de calcul sau o secvență de sunete pe care le scoateți atunci când comunicați un număr). Ceea ce te încurcă este faptul că nu vezi niciodată un număr, ci întotdeauna reprezentarea cifrelor acestuia. Așadar, ajungeți să credeți că numărul este reprezentarea.

Prin urmare, întrebarea corectă de pus nu este ” cum pot converti de la o bază la alta ” mai degrabă ” cum aflu ce număr este reprezentat de un șir dat de cifre ” și ” cum găsesc reprezentarea cifrelor unui număr dat „.

Deci, să producem două funcții în Python, una pentru conversia unei reprezentări cifre în un număr și altul pentru a face contrariul. Notă: când rulăm funcția Python, desigur, va tipări pe ecran numărul pe care l-a primit în baza 10. Dar acest lucru nu nu înseamnă că computerul păstrează numerele în bază 10 (nu este „t). Este irelevant modul în care computerul reprezintă numerele.

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 

Să le testăm:

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

Înarmat cu funcții de conversie, problema dvs. este rezolvată cu ușurință:

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

Un test :

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

Notă: am făcut nu treceți prin reprezentarea de bază 10! Am convertit reprezentarea de bază $ b $ în număr, apoi numărul în bază $ c $ . Numărul nu nu în nicio reprezentare. (De fapt, computerul trebuia să-l reprezinte cumva și îl reprezenta folosind semnale electrice și funky lucruri care se întâmplă în jetoane, dar cu siguranță acelea w Nici 0 „s și 1” s.)

Comentarii

  • Acest lucru nu ‘ nu convinge eu 100%. De fapt, ați convertit numărul într-o anumită reprezentare (deși puteți pretinde că nu știți ce este), deoarece computerele nu sunt matematicieni platonici, iar algoritmul dvs. nu poate converti o secvență arbitrară de cifre din baza $ b_1 $ în baza $ b_2 $; poate converti doar secvențe reprezentabile de mașina de beton. Python este fermecător de flexibil; C nu ar fi fost atât de iertător. Este perfect valabil să vă întrebați cum să convertiți șirurile arbitrare de la $ b_1 $ la $ b_2 $; cu toate acestea, acest lucru este posibil doar în timp liniar, cu excepția anumitor combinații de baze (de exemplu, 2 < – > 16)
  • Este valid să puneți întrebarea, dar pentru a găsi răspunsul corect, cel mai bine este să conștientizați faptul că numerele sunt entități abstracte.
  • Acest face să treacă numărul prin reprezentarea bazei 10, deoarece fromDigits returnează numărul din baza 10.
  • @anorton: Nu, cu siguranță nu . Python tipărește numărul pe ecran în reprezentarea de 10 cifre de bază, dar numărul în sine nu este stocat în acest fel. Ceea ce încerc să fac este că este irelevant modul în care numerele sunt implementate în Python. Nu conteaza. Singurul lucru care contează este că se comportă ca numerele.
  • În cele din urmă, o soluție generală pentru orice bază și nu se limitează la anumite cazuri de utilizare, baze mai mici de 36 sau instanțe în care puteți veni cu suficiente simboluri unice .

Răspuns

Cred că cel mai bun mod de a înțelege acest lucru este în discuția cu un străin (cel puțin ca o analogie).

Definiție $ x $ este un număr din baza $ b $ înseamnă că $ x $ este un șir de cifre $ < b $.

Exemple Șirul de cifre 10010011011 este un număr din baza 2, șirul 68416841531 este un număr din baza 10, BADCAFE este un număr din baza 16.

Acum Să presupunem că am crescut pe planeta QUUX, unde toată lumea este învățată să lucreze în $ q $ pentru întreaga lor viață și vă întâlnesc, care obișnuiește să bazeze $ b $. Deci îmi arăți un număr și ce fac? Am nevoie de o modalitate de ao interpreta:

Definiție Pot interpreta un număr din baza $ b $ (Notă: $ b $ este un număr din baza $ q $) după următoarea formulă

$$ \ begin {array} {rcl} [\! [\ epsilon] \!] & = & 0 \\ [\! [\ bar sd] \!] & = & [\! [\ bar s] \!] \ times b + d \ end {array} $$

unde $ \ epsilon $ denotă șirul gol, iar $ \ bar sd $ denotă un șir care se termină cu cifra $ d $. Vedeți dovada mea că adăugarea adaugă pentru o introducere la această notație.

Deci, ce s-a întâmplat aici? Mi-ați dat un număr în baza $ b $ și „l-am interpretat în baza $ q $ fără nicio filosofie ciudată despre ceea ce sunt cu adevărat numerele.

Cheie Cheia acestui lucru este că $ \ times $ și $ + $ I pe care le am sunt funcții care funcționează pe numere de bază $ q $. Acestea sunt algoritmi simpli definiți recursiv pe numere de bază $ q $ (șiruri de cifre).


Acest lucru poate părea puțin abstract deoarece am folosit variabile mai degrabă decât numere reale de-a lungul întregului. Deci, să presupunem că sunteți o creatură de bază 13 (folosind simboluri 0123456789XYZ $) și eu sunt folosit la baza 7 (ceea ce este mult mai sensibil) folosind simbolurile $ \ alpha \ beta \ gamma \ delta \ rho \ zeta \ xi $.

Deci, am văzut alfabetul tău și l-am tabelat astfel:

$$ \ begin {array} {| c | c || c | c || c | c |} \ hline 0 & \ alpha & 1 & \ beta & 2 & \ gamma \\ 3 & \ delta & 4 & \ rho & 5 & \ zeta \\ 6 & \ xi & 7 & \ beta \ alpha & 8 & \ beta \ beta \\ 9 & \ beta \ gamma & X \ beta \ delta & Y & \ beta \ rho \\ & & Z & \ beta \ zeta & & \\ \ hline \ end {array} $$

Deci știu că lucrați în baza $ \ beta \ xi $ și știu ce bază 7 numără orice cifră scrie corespunde.

Acum, dacă am discuta despre fizică și mi-ai spune despre constante fundamentale (să zicem) $ 60Z8 $, așa că trebuie să interpretez acest lucru:

$$ \ begin { array} {rcl} [\! [60Z8] \!] & = & \ xi (\ beta \ xi) ^ 3 + \ alpha (\ beta \ xi) ^ 2 + \ beta \ zeta (\ beta \ xi) + \ beta \ beta \\ \ end {array} $$

Deci încep prin multiplicarea $ \ beta \ zeta \ times \ beta \ xi $ dar pentru mine sunt lucruri de școală, îmi amintesc:

Tabelul de multiplicare Quux

$$ \ begin {array} {| c | cccccc |} \ hline \\ \ times & \ beta & \ gamma & \ delta & \ rho & \ zeta & \ xi \\ \ hline \ beta & \ beta & \ gamma & \ delta & \ rho & \ zeta & \ xi \\ \ gamma & \ gamma & \ rho & \ xi & \ beta \ beta & \ beta \ delta & \ beta \ zeta \\ \ delta & \ delta & \ xi & \ beta \ gamma & \ beta \ zeta & \ gamma \ beta & \ gamma \ rho \\ \ rho & \ rho & \ beta \ beta & \ beta \ zeta & \ gamma \ gamma & \ gamma \ xi & \ delta \ delta \\ \ zeta & \ zeta & \ beta \ delta & \ gamma \ beta & \ gamma \ xi & \ delta \ rho & \ rho \ gamma \\ \ xi & \ xi & \ beta \ zeta & \ gamma \ rho & \ delta \ delta & \ rho \ gamma & \ zeta \ beta \\ \ beta \ alpha & \ beta \ alpha & \ gamma \ alpha & \ delta \ alpha & \ rho \ alpha & \ zeta \ alpha & \ xi \ alpha \\ \ hline \ end {array} $$

deci pentru a găsi $ \ beta \ zeta \ times \ beta \ xi $ fac:

$$ \ begin {array} {ccc} & \ beta & \ ze ta \\ \ times & \ beta & \ xi \\ \ hline & \ xi & \ gamma \\ & \ rho & \\ \ beta & \ zeta & \\ \ hline \ delta & \ beta & \ gamma \\ \ gamma & & \\ \ end {array} $$

așa că am ajuns până aici

$$ \ begin {array} {rcl} [\! [60Z8] \!] & = & \ xi (\ beta \ xi) ^ 3 + \ alpha (\ beta \ xi) ^ 2 + \ beta \ zeta (\ beta \ xi) + \ beta \ beta \\ & = & \ xi (\ beta \ xi) ^ 3 + \ alpha (\ beta \ xi) ^ 2 + \ delta \ beta \ gamma + \ beta \ beta \\ \ end {array} $$

Acum trebuie să realizez adăugarea folosind algoritmul care a fost menționat anterior:

$$ \ begin {array} {ccc} \ delta & \ beta & \ gamma \\ & \ beta & \ beta \\ \ hline \ delta & \ gamma & \ delta \\ \ end {array} $$

deci

$$ \ begin {array} {rcl} [ \! [60Z8] \!] & = & \ xi (\ beta \ xi) ^ 3 + \ alpha (\ beta \ xi) ^ 2 + \ beta \ zeta (\ beta \ xi) + \ beta \ beta \\ & = & \ xi ( \ beta \ xi) ^ 3 + \ alpha (\ beta \ xi) ^ 2 + \ delta \ beta \ gamma + \ beta \ beta \\ & = & \ xi (\ beta \ xi) ^ 3 + \ alpha (\ beta \ xi) ^ 2 + \ delta \ gamma \ delta \\ \ end {array} $ $

și continuând în acest fel primesc $$ [\! [60Z8] \!] = \ zeta \ delta \ xi \ gamma \ rho. $$


În rezumat: Dacă am propria mea concepție despre număr în termeni de șiruri de cifre de bază $ q $, atunci am modalitate de a interpreta numerele dvs. de la baza $ b $ în propriul meu sistem, pe baza operațiilor aritmetice fundamentale – care operează nativ în baza $ q $.

Comentarii

  • Ei bine, asta a fost o mulțime de linii zgârcite. Cum aș face computerul să facă asta?
  • @Griffin, cred că puneți această întrebare (ciudată) prematur. Alegeți un limbaj de programare și tastați algoritmul pentru adunare și multiplicare pe numere de bază q (reprezentate ca liste de cifre), apoi definiți o funcție pentru a interpreta cifrele de bază b în numere de bază q și interpretați numerele de bază b în numere de bază q. Am ‘ am explicat toate acestea.
  • Lucrul este că știu conceptul pe care încerci să-l înfățișezi. Problema mea este că computerul meu nu poate ‘ să-ți folosească liniile zdrobitoare.
  • Știu ce ai explicat, dar punerea în practică este mult mai dificilă. Vedeți că definirea acelor cifre nu este ‘ t la fel de ușoară.
  • De ce ați scăzut cifra alfa în cea mai semnificativă poziție? Deoarece 6 = & xi ;, wouldn ‘ t 7 = & alpha; & alpha ;?

Răspuns

Acesta este un refactorizare (Python 3) din codul Andrej „s . În timp ce în numerele de cod ale lui Andrej sunt reprezentate printr-o listă de cifre (scalare), în următoarele coduri numerele sunt reprezentate prin o listă de simboluri arbitrare preluate dintr-un șir personalizat:

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) 

Pentru a efectua o conversie de la valoare la reprezentare într-o bază personalizată:

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

Pentru a efectua o conversie de la reprezentare (într-o bază personalizată) la valoare :

>>> 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 

Pentru a efectua o conversie de bază dintr-o bază personalizată în alta:

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

Comentarii

  • Bine ați venit pe site și vă mulțumim pentru contribuția dvs. Cu toate acestea, producerea unui cod sursă bine optimizat nu este ‘ ceea ce înseamnă cu adevărat acest site. Codul Andrej ‘ s clarifică conceptele, ceea ce este necesar pentru răspunsul său, dar îmbunătățirea codului dincolo de aceasta este o chestiune de programare, mai degrabă decât știința computerului .
  • @DavidRicherby Sunt parțial de acord, dar această contribuție a fost prea lungă pentru un comentariu și cel mai bun loc al său este undeva lângă răspunsul lui Andrej ‘, de aceea ‘ este motivul pentru care l-am postat aici. Oricum, dacă credeți că ‘ este mai bine, l-aș putea converti într-un comentariu cu un link către cod, dar nu ar fi ‘ un exces de purism?
  • În ciuda @David ‘ s ” site-purist ” obiecții, am găsit util răspunsul dvs., deoarece subliniază faptul că bazele implicate pot fi gândite în termeni mai abstracte ca ” alfabete ” de simboluri arbitrare de lungimi diferite – și nelimitat la intervalul obișnuit de 2-36 de caractere. De fapt, ați putea considera fluxurile de octeți ca ” cifre ” ale valorilor întregi de bază 256.

/ div>

Răspuns

Operația fundamentală a conversiei de bază este operația toDigits() a răspunsului @AndrejBauer. Cu toate acestea, pentru a face acest lucru, nu este necesar să creați un număr în reprezentarea internă a numerelor, care este practic o conversie de la și la reprezentarea de bază 2.Puteți efectua operațiile necesare în reprezentarea de bază originală.

Deci, primul pas este să faceți operații repetitive de diviziune modulo

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 

Deoarece reprezentarea internă este cifră, trebuie să faceți un specilaised funcție pentru testarea zero

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

În cele din urmă trebuie să efectuați operația modulo_div, care este de fapt diviziunea standard pe baza destinației așa cum am învățat la școală.

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 

doar o verificare de testare pentru a verifica dacă codul este corect:

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] 

Comentarii

  • Vă mulțumim pentru postare, dar vă rugăm să rețineți că ‘ nu suntem un site de codificare, deci un bloc mare de cod nu este ‘ nu este adecvat ca răspuns aici. Mai ales când întrebarea spune în mod explicit, ” Nu am ‘ nu am nevoie de cod, am nevoie doar de matematica de bază din spatele acestuia. ”
  • @DavidRicherby Am încercat să adaug text.
  • Mulțumesc. Și văd acolo ‘ o heck de o mulțime de cod pe această pagină, în ciuda a ceea ce am spus!
  • @ David: FWIW, cred că acest lucru răspunde OP ‘ este cea mai bună întrebare, deoarece arată cum să convertiți între cele două baze fără a converti mai întâi reprezentarea originalului într-o formă intermediară și apoi să o convertiți în baza de destinație.
  • Bună încercare, dar d este încă în baza 10, deci efectiv extrageți o porțiune mai mică de n convertind-o în baza 10, apoi transformând-o în baza dorită și colectându-le în rezultatul final.

Răspuns

Știu o modalitate ușoară de a face conversia de bază care nu necesită un program de computer. Este definită o modalitate de a converti de la orice bază la baza 2 și invers și apoi ascunderea dintr-o bază în alta bază prin conversia mai întâi de la prima bază la baza 2 apoi convertirea de la baza 2 la cealaltă bază. 2 este atât de ușor de înmulțit sau împărțit în orice bază.

Pentru a converti de la orice bază la baza 2, tot ce trebuie să faceți este să recunoașteți că pentru orice număr, dacă luați notația sa de bază 2 și începeți de la 0 și apoi pentru fiecare cifră în ordine de la stânga la dreapta dublă dacă acea cifră este zero și dublă decât adăugați 1 dacă acea cifră este 1, ajungeți la acel număr în sine. Acum, dat fiind acel număr din orice bază, puteți împărți la 2 în acea bază pentru a obține un coeficient și un rest. Dacă restul este 1, ultima cifră binară este 1 și dacă restul este 0, ultima cifră binară este 0. Împarte din nou la 2. Dacă restul este 1, a doua ultimă cifră este 1 și dacă restul este 0, a doua ultimă cifră este 0 și așa mai departe până când obțineți un coeficient de 0.

Pentru a converti de la baza 2 la orice bază, tot ce trebuie să faceți este în baza respectivă, începeți de la 0, apoi pentru fiecare cifră binară care merge de la stânga la dreapta, dublați în baza respectivă dacă acea cifră este 0 și dublați apoi adăugați 1 în acea bază dacă acea cifră este 1.

Comentarii

  • 2 is so easy to multiply or divide by in any base. Nu ‘ t vezi asta pentru baze ciudate care sunt mai mult de una de la orice putere de două (11 și 13, pentru început).

Răspunde

Puteți converti de la baza n la baza 10 fără nicio conversie la o bază intermediară.

Pentru a converti de la baza n la baza 9, de exemplu, luați algoritmul de conversie la baza 10 și înlocuiți „10” cu „9”. La fel pentru orice altă bază.

Lasă un răspuns

Adresa ta de email nu va fi publicată. Câmpurile obligatorii sunt marcate cu *