Hejka
Jak napisać program zmieniający liczbę z dowolnego systemu na dowolny? Proszę o jakieś tipy :D
Może chociaż zmieniający z systemu dwójkowego na dziesiętny. :)

- Rejestracja:ponad 7 lat
- Ostatnio:10 miesięcy
- Postów:262
https://www.matematyka.pl/31826.htm
Masz tu parę z dziesiętnego na binary/szesnastkowy, funkcja na parę linijek.

- Rejestracja:prawie 8 lat
- Ostatnio:2 dni
- Postów:913
Nie jestem dobrym Pythonowcem więc mogę się w tym momencie mylić, ale odpowiedziałbym tak:
print(hex(5)) # 0x5
print(oct(5)) # 0o5
print(bin(5)) # 0b101
var = int(0b101) # 5
var = int(0o5) # 5
var = int(0x5) # 5
1 grupa - dec -> inny system
2 grupa - inny system -> dec
- Rejestracja:prawie 14 lat
- Ostatnio:około 3 godziny
Typy dwójkowy, ósemkowy, dziesiętny i szesnastkowy są wbudowane w Pythona, jak np zamieniasz z dwójkowego na dziesiętny, to będzie int(0b i tu twoja liczba w systemie dwójkowym bez żadnych spacji), np int(0b1010). Z dziesiętnego na dwójkowy przeliczasz przez bin(liczba, zaś co do szesnastkowego to int(0xliczba) jak na dziesiętny oraz hex(liczba) jak z dziesiętnego na szesnastkowy. Dla ósemkowego to odpowiednio int(0oliczba) oraz oct(liczba)

- Rejestracja:prawie 8 lat
- Ostatnio:prawie 7 lat
- Postów:60
Przede wszystkim to pogoogluj trochę :)
print int('0x5', 16) # hex to int
print int('11111111', 2) # bin to int
i tak dalej :)
- Rejestracja:prawie 10 lat
- Ostatnio:około 19 godzin
- Lokalizacja:Tam gdzie jest (centy)metro...
#!/usr/bin/env python3
def convertInt2Base(value, base):
assert base > 1
import string
digs = string.digits + string.ascii_uppercase
sign = -1 if value < 0 else 1
if value == 0:
return digs[0]
value *= sign
digits = []
while value:
digits.append(digs[value % base])
value //= base
if sign < 0:
digits.append('-')
digits.reverse()
return ''.join(digits)
if __name__ == '__main__':
print(convertInt2Base(1024, 2))
print(convertInt2Base(255, 16))
print(convertInt2Base(10, 8))
Pewnie można szybciej i sprawniej ale często prostota jest ważniejsza niż "honowanie" kodu.

- Rejestracja:około 8 lat
- Ostatnio:4 minuty
- Postów:4884
Tu Masz prosty do zrozumienia algorytm rekurencyjny:
def dec_to_bin(n, out=""):
if n == 0:
return out[::-1]
out += str(n % 2)
return dec_to_bin(n // 2, out)
print(dec_to_bin(111))
Jak to działa? Jak widać:)
- Bierze resztę z dzielenia przez dwa wejściowej liczby i dodaje ją do wynikowego stringa
out
(to będzie ostatnia cyfra binarna wyniku) - Wykonuje to samo (rekurencyjnie) dla liczby 2 krotnie mniejszej (wywołanie funkcji od
n // 1, out
) - W miedzy czasie sprawdzany jest warunek zatrzymania sie rekurencji, jeśli w końcu wywołamy funkcję od zera (a będziemy musieli), to zwracamy wynik (odwrócony) i funkcja kończy działanie.
Notka o pythonie: out[::-1]
to jedno z miagicznych pythonowych "hojo mojo" - odwraca string lub listę;out=""
- parametr domyślny funkcji - nie tzreba go potem wpisywać przy wywołaniu (wołamy jak funkcję jednej zmiennej);n // 2
- to dzielenie w integerach, czyli5 /// 2
zwraca 2,1 // 3
zwraca 0, itd.
Zapewne rekurencja nie jest idealna (dla wielkich liczb rozwali stos ), ale prostota tego algorytmu czyni go idealnym przykładem do analizy, zrozumienia działania.
W drugą stronę(bin - dec) jest już prosto, bo, np:
1001(bin) = 1 * 2^3 + 0 * 2^2 + 0 * 2^1 + 1 * 2^0 = 9
Czyli wystarczy, posumować po długości stringa wejściowego.

- Rejestracja:prawie 8 lat
- Ostatnio:ponad 4 lata
- Lokalizacja:Częstochowa
- Postów:221
Niezabezpieczony przed złymi wartościami jak 1,5 systemu liczbowego. Ale powinno zdać egzamin, unikając rekurencji.
def ChangeDigitSystem(val, sys):
out = ""
while val > 0:
#~ print (divmod(val, sys))
val, mod = divmod(val, sys)
out += str(mod)
return out[::-1]
print(ChangeDigitSystem(721, 2))



- Rejestracja:prawie 8 lat
- Ostatnio:ponad 4 lata
- Lokalizacja:Częstochowa
- Postów:221
Ah, spojrzałem na pytanie odpowiadając na komentarz, w sumie co do wyższych systemów liczbowych, polecam słownik.
Jeśli ci potrzebny wyższy niż 16-stkowy, to według tego możesz podziałać :).
No i też najprostszy sposób konwersji na dziesiętny. Jak połączysz te dwa, możesz sobie zrobić konwersję z dowolnego na dowolny. Wtedy polecam zapoznać się z zasadami jeśli podstawa systemu tego drugiego jest potęgą/dzielnikiem ;p
def ChangeDigitSystem(val, sys):
lett = {10: "A", 11: "B", 12: "C", 13: "D", 14: "E", 15: "F"}
out = ""
while val > 0:
#~ print (divmod(val, sys))
val, mod = divmod(val, sys)
if mod > 9:
mod = lett.get(mod)
out += str(mod)
return out[::-1]
def ReverseTo10digitSystem(val, basis):
lett = {"0": 0, "1": 1, "2": 2, "3": 3, "4": 4, "5": 5, "6": 6, "7": 7, "8": 8, "9": 9, "A": 10, "B": 11, "C": 12, "D": 13, "E": 14, "F": 15}
summ = 0
base = 1
while val:
summ += lett.get(val[-1]) * base
#~ print(val, summ, base, "*", lett.get(val[-1]))
base *= basis
val = val[:-1]
return summ
print(ChangeDigitSystem(721, 2))
print(ChangeDigitSystem(721, 16))
print(ReverseTo10digitSystem("1011010001", 2))
print(ReverseTo10digitSystem("2D1", 16))
#~ Tip, średnioczytelny z generatorami. Ale też się da ;p.
def ReverseTo10digitSystem(val, basis):
lett = {"0": 0, "1": 1, "2": 2, "3": 3, "4": 4, "5": 5, "6": 6, "7": 7, "8": 8, "9": 9, "A": 10, "B": 11, "C": 12, "D": 13, "E": 14, "F": 15}
return sum([lett.get(x)*base for x, base in zip(val[::-1], [basis ** i for i in range(len(val))])])

lett = {a: b for a, b in zip('0123456789ABCDEF', range(16))}


import string; dict(zip(range(16), string.digits + 'ABCDEF'))
. Można tego mnóstwo wymyślać. Poza tym, polecam taki talk z PyCona: https://www.youtube.com/watch?v=wf-BqAjZb8M

from string import digits, ascii_letters; dict(zip(range(basis), digits+ascii_letters))
. Oczywiście jest to, to samo, tylko ogranicza/rozszerza zakres na możliwości systemów liczbowych. zip kończy po zakończeniu krótszego łańcucha, który wyznacza tutaj basis :). Dla systemu dwójkowego działa dużo szybciej. Ale szybsze i prostsze do użytku jest na przykład: int("2D1", 16)
;>