Python pozwala na łatwe utworzenie liczby całkowitej z ciągu danej bazy za pośrednictwem
int(str, base).
Chcę wykonać odwrotność: utworzenie ciągu z liczby całkowitej , tzn. Chcę jakąś funkcję int2base(num, base)
, taką jak:
int(int2base(x, b), b) == x
Nazwa funkcji / kolejność argumentów jest nieistotna.
Dla dowolnej liczby x
i bazy b
, int()
które zaakceptują.
Jest to prosta funkcja do napisania: w rzeczywistości jest łatwiejsza niż opisanie jej w tym pytaniu. Mam jednak wrażenie, że czegoś mi brakuje.
Wiem o funkcjach bin
, oct
, hex
, ale nie można ich używać z kilku powodów:
Te funkcje nie są dostępne w starszych wersjach Pythona, z którymi potrzebuję zgodności z (2.2)
Chcę ogólnego rozwiązania, które można nazwać tak samo dla różnych baz
Chcę zezwolić na zasady inne niż 2, 8, 16
Odpowiedzi:
Jeśli potrzebujesz zgodności ze starymi wersjami Pythona, możesz albo użyć gmpy (który obejmuje szybką, całkowicie ogólną funkcję konwersji int-na-string i może być zbudowany dla takich starożytnych wersji - być może będziesz musiał wypróbować starsze wersje od ostatnie nie zostały przetestowane pod kątem czcigodnych wydań Python i GMP, tylko nieco nowsze), lub, dla mniejszej prędkości, ale większej wygody, użyj kodu Python - np. najprościej:
źródło
gmpy2.digits(x, base)
.digs = string.digits + string.lowercase + string.uppercase
string.digits + string.letters
)x //= base
który zachowuje się jak/=
w Pythonie 2 podczas upuszczania dziesiętnych. Ta odpowiedź powinna zawierać zastrzeżenie, że dotyczy Pythona 2.Co zaskakujące, ludzie podawali tylko rozwiązania, które przekształcają się w małe bazy (mniejsze niż długość alfabetu angielskiego). Nie próbowano podać rozwiązania, które przekształciłoby się w dowolną bazę od 2 do nieskończoności.
Oto bardzo proste rozwiązanie:
więc jeśli chcesz przekonwertować jakąś super ogromną liczbę na bazę
577
,numberToBase(67854 ** 15 - 102, 577)
, Daje poprawne rozwiązanie:[4, 473, 131, 96, 431, 285, 524, 486, 28, 23, 16, 82, 292, 538, 149, 25, 41, 483, 100, 517, 131, 28, 0, 435, 197, 264, 455]
,Które możesz później przekonwertować na dowolną bazę, którą chcesz
źródło
int(4545,16)
podał „11c1” iint(4545,60)
„1:15:45”. Tak więc funkcja spełniała trzy funkcje: konwertuje do formatu dziesiętnego, komputerowego i znacznika czasu.digits
?ref: http://code.activestate.com/recipes/65212/
Należy pamiętać, że może to prowadzić do
dla bardzo dużych liczb całkowitych.
źródło
len(numerals)
, a (b)num % b
na szczęście <len(numerals)
. np. chociażnumerals
łańcuch ma tylko 36 znaków, baseN (60, 40) zwraca,'1k'
podczas gdy baseN (79, 40) podnosi anIndexError
. Oba powinny powodować jakiś błąd. Kod powinien zostać zmieniony, aby zgłosić błąd, jeślinot 2 <= base <= len(numerals)
.b
pewno nie przekroczyłoby tolen(numerals)
, no cóż, powodzenia.return numerals[0] if num == 0 else baseN(num // b, b, numerals).lstrip(numerals[0]) + numerals[num % b]
jest równie krótka.źródło
0
jest niepotrzebne. Oto dokumentacja Python 2: docs.python.org/2/library/string.html#format-string-syntaxhex(100)[2:]
,oct(100)[2:]
ibin(100)[2:]
.Świetne odpowiedzi! Myślę, że odpowiedź na moje pytanie brzmiała „nie”. Nie brakowało mi jakiegoś oczywistego rozwiązania. Oto funkcja, której użyję, która zagęszcza dobre pomysły wyrażone w odpowiedziach.
źródło
Rekurencyjne
Chciałbym uprościć ten najbardziej głosowało odpowiedź do:
Z tą samą radą dla
RuntimeError: maximum recursion depth exceeded in cmp
bardzo dużych liczb całkowitych i liczb ujemnych. (Możesz użyćsys.setrecursionlimit(new_limit)
)Wielokrotny
Aby uniknąć problemów z rekurencją :
źródło
return BS[0] if not n
wtedy warunek zatrzymania ? Na wypadek, gdybyś chciał użyć fantazyjnych cyfr, tak jak ja :)return BS[n] if n < b else to_base(n // b) + BN[n % b]
Python nie ma wbudowanej funkcji do drukowania liczb całkowitych w dowolnej bazie. Będziesz musiał napisać własny, jeśli chcesz.
źródło
Możesz skorzystać
baseconv.py
z mojego projektu: https://github.com/semente/python-baseconvPrzykładowe użycie:
Istnieje kilka konwertery bultin jak na przykład
baseconv.base2
,baseconv.base16
ibaseconv.base64
.źródło
>>> numpy.base_repr(10, base=3) '101'
źródło
clac
związanych z czasem ładowania. Wstępne ładowanie numpy więcej niż trzykrotnie zwiększa czas wykonywania prostej oceny wyrażeń w clac: np.clac 1+1
Z około 40 ms do 140 ms.numpy.base_repr()
ma limit 36 jako podstawę. W przeciwnym razie wyrzucaValueError
http://code.activestate.com/recipes/65212/
Oto kolejny z tego samego linku
źródło
Zrobiłem dla tego pakiet pip.
Polecam korzystanie z moich bases.py https://github.com/kamijoutouma/bases.py, który został zainspirowany bases.js
patrz https://github.com/kamijoutouma/bases.py#known-basesalphabets, aby dowiedzieć się, jakie zasady są użyteczne
EDYCJA: pip link https://pypi.python.org/pypi/bases.py/0.2.2
źródło
wynik:
źródło
other-base
jest taki sam jakother - base
, więc powinieneś użyćother_base
decimal
wynosi zero.źródło
Rekurencyjne rozwiązanie dla zainteresowanych. Oczywiście nie będzie to działać z ujemnymi wartościami binarnymi. Musisz wdrożyć Two's Complement.
źródło
wyjaśnienie
W dowolnej bazie każda liczba jest równa
a1+a2*base**2+a3*base**3...
„Misja” polega na znalezieniu wszystkich „a”.Dla każdego
N=1,2,3...
kodu izoluje sięaN*base**N
przez „moudulowanie” przez b, dlab=base**(N+1)
którego wycina się wszystkie a jest większe niż N, i przecina wszystkie a, że ich numer seryjny jest mniejszy niż N, zmniejszając za każdym razem, gdy func jest wywoływany przez prądaN*base**N
.Podstawa% (podstawa-1) == 1 jej podstawa ** p% (podstawa-1) == 1 i dlatego q * podstawa ^ p% (podstawa-1) == q z jednym wyjątkiem, gdy q = podstawa-1 która zwraca 0. Aby to naprawić w przypadku, gdy zwraca 0, func sprawdza, czy to 0 od początku.
Zalety
w tej próbce jest tylko jedna multiplikacja (zamiast dzielenia) i niektóre moudule, które względnie zajmują mało czasu.
źródło
źródło
źródło
Oto przykład, jak przekonwertować liczbę dowolnej bazy na inną bazę.
źródło
źródło
Kolejny krótki (i łatwiejszy do zrozumienia imo):
I przy odpowiedniej obsłudze wyjątków:
źródło
Inne rozwiązanie, działające z bazą 2 do 10, wymaga modyfikacji dla wyższych baz:
Przykład:
źródło
Oto wersja rekurencyjna, która obsługuje podpisane liczby całkowite i cyfry niestandardowe.
źródło
Ciągi nie są jedynym wyborem do reprezentowania liczb: możesz użyć listy liczb całkowitych do przedstawienia kolejności każdej cyfry. Można je łatwo przekonwertować na ciąg.
Żadna z odpowiedzi nie odrzuca podstawy <2; i większość będzie działać bardzo wolno lub ulegnie awarii z przepełnieniem stosu dla bardzo dużych liczb (takich jak 56789 ** 43210). Aby uniknąć takich awarii, zmniejsz szybko tak:
Speedwise,
n_to_base
jest porównywalny zstr
dużymi liczbami (około 0,3 s na moim komputerze), ale jeśli porównasz go,hex
możesz być zaskoczony (około 0,3 ms na moim komputerze lub 1000x szybciej). Powodem jest to, że duża liczba całkowita jest przechowywana w pamięci w bazie 256 (bajty). Każdy bajt można po prostu przekonwertować na dwuznakowy ciąg szesnastkowy. To wyrównanie ma miejsce tylko dla zasad, które są potęgami dwóch, dlatego istnieją specjalne przypadki dla 2,8 i 16 (i base64, ascii, utf16, utf32).Rozważ ostatnią cyfrę ciągu dziesiętnego. Jak to się ma do sekwencji bajtów, która tworzy jego liczbę całkowitą? Załóżmy, etykieta bajty
s[i]
zs[0]
bycia najmniej znaczący (little endian). Zatem ostatnia cyfra tosum([s[i]*(256**i) % 10 for i in range(n)])
. Zdarza się, że 256 ** i kończy się na 6 dla i> 0 (6 * 6 = 36), więc ostatnia cyfra to(s[0]*5 + sum(s)*6)%10
. Z tego widać, że ostatnia cyfra zależy od sumy wszystkich bajtów. Ta nielokalna właściwość utrudnia konwersję na dziesiętne.źródło
źródło
Cóż, osobiście korzystam z tej napisanej przeze mnie funkcji
Oto jak możesz go użyć
print(to_base(7, base=2))
Wynik:
"111"
print(to_base(23, base=3))
Wynik:
"212"
Proszę sugerować ulepszenia w moim kodzie.
źródło
źródło
To stare pytanie, ale pomyślałem, że podzielę się tym, ponieważ uważam, że jest to nieco prostsze niż inne odpowiedzi (dobre dla baz od 2 do 36):
źródło
Nie widziałem tutaj żadnych konwerterów float. I brakowało mi grupowania na zawsze trzy cyfry.
DO ZROBIENIA:
- liczba w ekspresji naukowej
(n.nnnnnn*10**(exp)
-'10'
jestself.baseDigits[1::-1]/self.to_string(len (self.baseDigits))
-from_string-function.
-baza 1 -> cyfry rzymskie?
-prof kompleks z aglami
Oto moje rozwiązanie:
źródło
wynik:
na konwersję na dowolną bazę, odwrotność też jest łatwa.
źródło
NameError: global name 'n' is not defined
. Czydivmod(x, n)
ma byćdivmod(x, b)
?