किसी भी आधार में एक पूर्णांक को एक स्ट्रिंग में कैसे परिवर्तित किया जाए?


203

पायथन किसी दिए गए आधार की एक स्ट्रिंग से पूर्णांक के आसान निर्माण की अनुमति देता है

int(str, base). 

मैं उलटा प्रदर्शन करना चाहता हूं: पूर्णांक से एक स्ट्रिंग का निर्माण , यानी मैं कुछ फ़ंक्शन चाहता हूं int2base(num, base), जैसे:

int(int2base(x, b), b) == x

फ़ंक्शन का नाम / तर्क क्रम महत्वहीन है।

किसी भी संख्या xऔर आधार के लिए bजो int()स्वीकार करेगा।

यह लिखने का एक आसान कार्य है: वास्तव में इस प्रश्न में इसका वर्णन करने की तुलना में यह आसान है। हालाँकि, मुझे लगता है कि मुझे कुछ याद आ रहा है।

मैं कार्यों के बारे में पता bin, oct, hex, लेकिन मैं उन्हें कुछ कारणों के लिए उपयोग नहीं कर सकते:

  • वे कार्य पायथन के पुराने संस्करणों पर उपलब्ध नहीं हैं, जिनके साथ मुझे (2.2) संगतता की आवश्यकता है

  • मैं एक सामान्य समाधान चाहता हूं जिसे अलग-अलग आधारों के लिए एक ही तरीका कहा जा सकता है

  • मैं 2, 8, 16 के अलावा अन्य आधारों की अनुमति देना चाहता हूं

सम्बंधित


5
हैरानी की बात यह है कि किसी ने एक समाधान नहीं दिया जो मनमाने बड़े आधार (1023) के साथ काम करता है। यदि आपको इसकी आवश्यकता है, तो मेरे समाधान की जांच करें जो हर आधार (2 से inf) के लिए काम करता है stackoverflow.com/a/28666223/1090562
सल्वाडोर डाली

जवाबों:


98

यदि आपको पायथन के प्राचीन संस्करणों के साथ संगतता की आवश्यकता है, तो आप या तो gmpy का उपयोग कर सकते हैं (जिसमें एक तेज, पूरी तरह से सामान्य इंट-टू-स्ट्रिंग रूपांतरण फ़ंक्शन शामिल है, और इस तरह के प्राचीन संस्करणों के लिए बनाया जा सकता है - आपको पुराने रिलीज़ को आज़माने की आवश्यकता हो सकती है हाल ही में आदरणीय अजगर और जीएमपी रिलीज के लिए परीक्षण नहीं किया गया है, केवल कुछ हाल ही में), या, कम गति के लिए लेकिन अधिक सुविधा के लिए, पायथन कोड का उपयोग करें - जैसे, सबसे सरल:

import string
digs = string.digits + string.ascii_letters


def int2base(x, base):
    if x < 0:
        sign = -1
    elif x == 0:
        return digs[0]
    else:
        sign = 1

    x *= sign
    digits = []

    while x:
        digits.append(digs[int(x % base)])
        x = int(x / base)

    if sign < 0:
        digits.append('-')

    digits.reverse()

    return ''.join(digits)

8
बस (gmpy2) के मामले में एलेक्स एलेक्स की बात कहती है gmpy2.digits(x, base)
mlvjjr

2
यह मेरे ध्यान में लाया गया था कि कुछ मामलों में आधार की आवश्यकता होती है> 36 और इसलिए digs होना चाहिएdigs = string.digits + string.lowercase + string.uppercase
पॉल

4
(या string.digits + string.letters)
कोजिरो

3
पायथन में डिफ़ॉल्ट रूप से कन्वर्ट-बेस-एन-टू-स्ट्रिंग को शामिल क्यों नहीं किया गया है? (यह जावास्क्रिप्ट में है।) हाँ, हम सभी अपने स्वयं के कार्यान्वयन को लिख सकते हैं, लेकिन मैं इस साइट पर और अन्य जगहों पर खोज कर रहा हूं, और उनमें से कई में कीड़े हैं। मुख्य वितरण में शामिल एक परीक्षण, सम्मानित संस्करण के लिए बेहतर है।
जेसन एस

4
@ lordscales91 आप दशमलव को छोड़ने में पायथन 2 की x //= baseतरह व्यवहार कर सकते हैं /=। इस उत्तर में एक डिस्क्लेमर शामिल होना चाहिए कि यह पाइथन 2 के लिए है
नूमेनन

100

हैरानी की बात है, लोग केवल समाधान दे रहे थे जो छोटे ठिकानों में बदल जाते हैं (छोटे तब अंग्रेजी वर्णमाला की लंबाई)। कोई समाधान देने की कोशिश नहीं की गई जो 2 से अनंत तक किसी भी मनमाने आधार पर धर्मान्तरित हो।

तो यहाँ एक सुपर सरल उपाय है:

def numberToBase(n, b):
    if n == 0:
        return [0]
    digits = []
    while n:
        digits.append(int(n % b))
        n //= b
    return digits[::-1]

इसलिए यदि आपको आधार में कुछ सुपर विशाल संख्या को बदलने की आवश्यकता है 577,

numberToBase(67854 ** 15 - 102, 577), आप एक सही समाधान दे देंगे: [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],

जिसे आप बाद में अपने इच्छित किसी भी आधार में बदल सकते हैं


कॉलेज में मैं एक ऐसे फ़ंक्शन के साथ आया, जो आधारों को मानक अंकन में 20 से नीचे, और 20 को आधार बनाकर 'कोलोन सीमांकित दशमलव' से अधिक है। उदाहरण के लिए, int(4545,16)"11c1" int(4545,60)दिया और "1:15:45" दिया। इस प्रकार फ़ंक्शन ने ट्रिपल ड्यूटी किया: दशमलव, कंप्यूटरिश और टाइमस्टैम्प स्वरूपों में परिवर्तित करना।
पीटर रेहनम

1
इस विधि के लिए उलटा कार्य क्या है?
सोहराब टी

यह 3 कारणों से पूछे गए प्रश्न का उत्तर नहीं देता है, 1: मौजूदा लाइब्रेरी फ़ंक्शन के लिए पूछे गए प्रश्न का कार्यान्वयन 2 नहीं है: प्रश्न स्ट्रिंग के लिए पूछा गया है, यह एक सूची 3 का उत्पादन करता है: यह इंट (str) के लिए एक व्युत्क्रम नहीं है बेस) बेसिन।
प्लगवॉश

@plugwash 1) कुछ समय पर आप देखेंगे कि कभी-कभी कोई अंतर्निहित लाइब्रेरी फ़ंक्शन नहीं होता है जो आप चाहते हैं, इसलिए आपको अपना खुद का लिखना होगा। यदि आप असहमत हैं, तो आप अपने समाधान का निर्माण एक बेसिन फ़ंक्शन के साथ कर सकते हैं, जो आधार संख्या को आधार संख्या 577 में बदल सकता है। 2) यह समझ में कमी के कारण है कि कुछ आधार में संख्या क्या है। 3) मैं आपको थोड़ा सोचने के लिए प्रोत्साहित करता हूं कि आपकी पद्धति में आधार केवल n = = 36 के लिए क्यों काम करता है। एक बार जब आप काम कर लेते हैं, तो यह स्पष्ट हो जाएगा कि मेरा कार्य एक सूची क्यों लौटाता है और इसके हस्ताक्षर हैं।
साल्वाडोर डाली

1
यह नकारात्मक संख्याओं के लिए काम नहीं करता है, और मुझे यकीन नहीं है कि इसे मूल रूप से बदलने के बिना इसे कैसे काम करना है। शायद एक साइन बिट, 1 या -1 जोड़कर, सबसे ऊपर digits?
वेजेंड्रिया

89
def baseN(num,b,numerals="0123456789abcdefghijklmnopqrstuvwxyz"):
    return ((num == 0) and numerals[0]) or (baseN(num // b, b, numerals).lstrip(numerals[0]) + numerals[num % b])

रेफरी: http://code.activestate.com/recipes/65212/

कृपया ध्यान रखें कि यह हो सकता है

RuntimeError: maximum recursion depth exceeded in cmp

बहुत बड़े पूर्णांकों के लिए।


5
अपनी संक्षिप्तता में सुरुचिपूर्ण। यह गैर-नकारात्मक पूर्णांक के लिए अजगर 2.2.3 के तहत काम करने लगता है। एक नकारात्मक संख्या असीम रूप से पीछे हट जाती है।
मार्क बोरिंगडिंग

+1 उपयोगी; जब कोई समस्या '0' के साथ शुरू नहीं हुई तो एक समस्या तय की
9

4
यह चुपचाप विफल रहता है (ए) जब आधार है> len(numerals), और (बी) num % bभाग्य से है, < len(numerals)। उदाहरण के लिए, हालांकि numeralsस्ट्रिंग की लंबाई केवल 36 वर्ण है, बेसन (60, 40) रिटर्न '1k'जबकि बेसन (79, 40) एक उठता है IndexError। दोनों को किसी न किसी तरह की त्रुटि उठानी चाहिए। यदि कोई त्रुटि हो तो कोड को संशोधित किया जाना चाहिए not 2 <= base <= len(numerals)
क्रिस जॉनसन

3
@ तो, मेरी बात यह है कि जैसा कि लिखा गया कोड बहुत बुरे तरीके से विफल होता है (चुपचाप, भ्रामक जवाब दे रहा है) और आसानी से तय किया जा सकता है। यदि आप कह रहे हैं कि कोई त्रुटि नहीं होगी यदि आप पहले से जानते थे, निश्चित रूप से, bतो यह len(numerals)आपके लिए अच्छा नहीं होगा , अच्छी बात है।
क्रिस जॉनसन

1
यहां शॉर्ट-सर्कुलेटिंग का उपयोग अनावश्यक रूप से भ्रमित करने वाला लगता है ... क्यों न केवल एक if स्टेटमेंट का उपयोग किया जाए ... लाइन return numerals[0] if num == 0 else baseN(num // b, b, numerals).lstrip(numerals[0]) + numerals[num % b]बस संक्षिप्त रूप में है।
इयान हिंक्स

84
"{0:b}".format(100) # bin: 1100100
"{0:x}".format(100) # hex: 64
"{0:o}".format(100) # oct: 144

46
लेकिन यह केवल उन तीन ठिकानों को करता है?
थॉमस अहले

3
हां, दुर्भाग्य से आप कस्टम इंट बेस को निर्दिष्ट नहीं कर सकते। अधिक जानकारी यहाँ है: docs.python.org/library/string.html#formatstrings
Rost

3
0अनावश्यक है। : यहाँ अजगर 2 प्रलेखन है docs.python.org/2/library/string.html#format-string-syntax
ईव्जेनी Sergeev

7
आप उसी परिणाम को प्राप्त कर सकते हैं hex(100)[2:], oct(100)[2:]और bin(100)[2:]
सासन

2
@ ईवगेनीसर्जव: यह केवल 2.7 / 3.1 + पर अनावश्यक है। 2.6 पर, स्पष्ट स्थिति (या नाम) की आवश्यकता है।
शैडो रेंजर

21

शानदार जवाब! मुझे लगता है कि मेरे प्रश्न का उत्तर "नहीं" था मैं कुछ स्पष्ट समाधान नहीं याद कर रहा था। यहां वह फ़ंक्शन है जो मैं उपयोग करूंगा जो उत्तरों में व्यक्त अच्छे विचारों को प्रस्तुत करता है।

  • वर्णों की कॉलर-सप्लाई मैपिंग की अनुमति दें (बेस 64 एनकोड की अनुमति देता है)
  • नकारात्मक और शून्य के लिए जाँच
  • स्ट्रिंग्स के ट्यूपल्स में जटिल संख्याओं को मैप करता है


def int2base(x,b,alphabet='0123456789abcdefghijklmnopqrstuvwxyz'):
    'convert an integer to its string representation in a given base'
    if b<2 or b>len(alphabet):
        if b==64: # assume base64 rather than raise error
            alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
        else:
            raise AssertionError("int2base base out of range")
    if isinstance(x,complex): # return a tuple
        return ( int2base(x.real,b,alphabet) , int2base(x.imag,b,alphabet) )
    if x<=0:
        if x==0:
            return alphabet[0]
        else:
            return  '-' + int2base(-x,b,alphabet)
    # else x is non-negative real
    rets=''
    while x>0:
        x,idx = divmod(x,b)
        rets = alphabet[idx] + rets
    return rets


4
आप हमारे फ़ंक्शन के आधार 64 आउटपुट को पूर्णांक में कैसे परिवर्तित करते हैं?
detly

18

पुनरावर्ती

मैं होगा आसान बनाने में सबसे मतदान जवाब करने के लिए:

BS="0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"
def to_base(n, b): 
    return "0" if not n else to_base(n//b, b).lstrip("0") + BS[n%b]

RuntimeError: maximum recursion depth exceeded in cmpबहुत बड़े पूर्णांक और ऋणात्मक संख्याओं के लिए एक ही सलाह के साथ । (आप उपयोग कर सकते हैं sys.setrecursionlimit(new_limit))

चलने का

पुनरावृत्ति की समस्याओं से बचने के लिए :

BS="0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"
def to_base(s, b):
    res = ""
    while s:
        res+=BS[s%b]
        s//= b
    return res[::-1] or "0"

2
खूबसूरती से, और पुस्तकालय के बिना refactored।
गिआमपोलो फेरादिनी

रोक हालत return BS[0] if not nतो नहीं होना चाहिए ? बस अगर आप फैंसी अंकों का उपयोग करना चाहते हैं, जैसे कि मैं :)
अरनौद पी

@ArnaudP ने सहमति व्यक्त की। : यह एक मेरे लिए काम करताreturn BS[n] if n < b else to_base(n // b) + BN[n % b]
जेन्स

15

एक मनमाने ढंग से आधार में पूर्णांक प्रिंट करने के लिए पायथन में एक अंतर्निहित कार्य नहीं है। यदि आप चाहते हैं तो आपको अपना खुद का लिखना होगा।


13

आप baseconv.pyमेरे प्रोजेक्ट से उपयोग कर सकते हैं : https://github.com/semente/python-baseconv

नमूना उपयोग:

>>> from baseconv import BaseConverter
>>> base20 = BaseConverter('0123456789abcdefghij')
>>> base20.encode(1234)
'31e'
>>> base20.decode('31e')
'1234'
>>> base20.encode(-1234)
'-31e'
>>> base20.decode('-31e')
'-1234'
>>> base11 = BaseConverter('0123456789-', sign='$')
>>> base11.encode('$1234')
'$-22'
>>> base11.decode('$-22')
'$1234'

उदाहरण के लिए कुछ बुल्टिन कन्वर्टर्स हैं baseconv.base2, baseconv.base16और baseconv.base64


12

>>> numpy.base_repr(10, base=3) '101'


अच्छा समाधान है। मेरे मामले में, मैं clacलोडिंग-टाइम चिंताओं के लिए सुन्न से बच रहा था । क्लैक से अधिक खसखस ​​को प्री-लोड करना क्लैक् में सरल अभिव्यक्ति मूल्यांकन का रनटाइम: जैसे clac 1+1 लगभग 40ms से 140ms तक चला गया।
मार्क बोरिंगडिंग

1
ध्यान दें कि numpy.base_repr()इसके आधार के रूप में 36 की सीमा है। अन्यथा यह एकValueError
sbdchd

जो "int" फ़ंक्शन में निर्मित की सीमा से मेल खाता है। बड़े बेसों को यह तय करने की आवश्यकता होती है कि पत्रों को चलाने पर क्या करना है,
प्लग

4

http://code.activestate.com/recipes/65212/

def base10toN(num,n):
    """Change a  to a base-n number.
    Up to base-36 is supported without special notation."""
    num_rep={10:'a',
         11:'b',
         12:'c',
         13:'d',
         14:'e',
         15:'f',
         16:'g',
         17:'h',
         18:'i',
         19:'j',
         20:'k',
         21:'l',
         22:'m',
         23:'n',
         24:'o',
         25:'p',
         26:'q',
         27:'r',
         28:'s',
         29:'t',
         30:'u',
         31:'v',
         32:'w',
         33:'x',
         34:'y',
         35:'z'}
    new_num_string=''
    current=num
    while current!=0:
        remainder=current%n
        if 36>remainder>9:
            remainder_string=num_rep[remainder]
        elif remainder>=36:
            remainder_string='('+str(remainder)+')'
        else:
            remainder_string=str(remainder)
        new_num_string=remainder_string+new_num_string
        current=current/n
    return new_num_string

यहाँ उसी कड़ी में से एक और एक है

def baseconvert(n, base):
    """convert positive decimal integer n to equivalent in another base (2-36)"""

    digits = "0123456789abcdefghijklmnopqrstuvwxyz"

    try:
        n = int(n)
        base = int(base)
    except:
        return ""

    if n < 0 or base < 2 or base > 36:
        return ""

    s = ""
    while 1:
        r = n % base
        s = digits[r] + s
        n = n / base
        if n == 0:
            break

    return s

Base10toN संख्या के मामले में == 0.
क्रेप

3

मैंने इसके लिए एक पाइप पैकेज बनाया।

मैं आपको अपने bases.py https://github.com/kamijoutouma/bases.py का उपयोग करने की सलाह देता हूं, जो bases.Ds से प्रेरित था

from bases import Bases
bases = Bases()

bases.toBase16(200)                // => 'c8'
bases.toBase(200, 16)              // => 'c8'
bases.toBase62(99999)              // => 'q0T'
bases.toBase(200, 62)              // => 'q0T'
bases.toAlphabet(300, 'aAbBcC')    // => 'Abba'

bases.fromBase16('c8')               // => 200
bases.fromBase('c8', 16)             // => 200
bases.fromBase62('q0T')              // => 99999
bases.fromBase('q0T', 62)            // => 99999
bases.fromAlphabet('Abba', 'aAbBcC') // => 300

आधारभूत क्या हैं, इसके लिए https://github.com/kamijoutouma/bases.py# परिचित-basesalphabets का संदर्भ लें

EDIT: पाइप लिंक https://pypi.python.org/pypi/bases.py/0.2.2


यह निर्दिष्ट ठिकानों के लिए एक आकर्षण की तरह काम करता है ।
एगी हैमर्थीफ़

यह अब तक का सबसे अच्छा जवाब है! और पाइप पैकेजिंग के लिए धन्यवाद!
18

3
def base(decimal ,base) :
    list = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"
    other_base = ""
    while decimal != 0 :
        other_base = list[decimal % base] + other_base
        decimal    = decimal / base
    if other_base == "":
        other_base = "0"
    return other_base

print base(31 ,16)

उत्पादन:

"1F"


other-baseजैसा है other - base, वैसे ही आपको उपयोग करना चाहिएother_base
mbomb007

इसके अलावा, यह सही ढंग से काम नहीं करता है यदि decimalशून्य है।
mbomb007

1
>>> import string
>>> def int2base(integer, base):
        if not integer: return '0'
        sign = 1 if integer > 0 else -1
        alphanum = string.digits + string.ascii_lowercase
        nums = alphanum[:base]
        res = ''
        integer *= sign
        while integer:
                integer, mod = divmod(integer, base)
                res += nums[mod]
        return ('' if sign == 1 else '-') + res[::-1]


>>> int2base(-15645, 23)
'-16d5'
>>> int2base(213, 21)
'a3'

1

रुचि रखने वालों के लिए एक पुनरावर्ती समाधान। बेशक, यह नकारात्मक द्विआधारी मूल्यों के साथ काम नहीं करेगा। आपको दो के पूरक को लागू करने की आवश्यकता होगी।

def generateBase36Alphabet():
    return ''.join([str(i) for i in range(10)]+[chr(i+65) for i in range(26)])

def generateAlphabet(base):
    return generateBase36Alphabet()[:base]

def intToStr(n, base, alphabet):
    def toStr(n, base, alphabet):
        return alphabet[n] if n < base else toStr(n//base,base,alphabet) + alphabet[n%base]
    return ('-' if n < 0 else '') + toStr(abs(n), base, alphabet)

print('{} -> {}'.format(-31, intToStr(-31, 16, generateAlphabet(16)))) # -31 -> -1F

1
def int2base(a, base, numerals="0123456789abcdefghijklmnopqrstuvwxyz"):
    baseit = lambda a=a, b=base: (not a) and numerals[0]  or baseit(a-a%b,b*base)+numerals[a%b%(base-1) or (a%b) and (base-1)]
    return baseit()

व्याख्या

किसी भी आधार में हर संख्या a1+a2*base**2+a3*base**3..."मिशन" के बराबर है , सभी को खोजना है।

प्रत्येक N=1,2,3...कोड के लिए aN*base**N"mouduling" द्वारा बी को अलग किया जाता है, b=base**(N+1) जिसके लिए सभी एन की तुलना में बड़े होते हैं, और सभी के स्लाइसिंग करते हैं कि उनके सीरियल एन की तुलना में छोटा होता है हर बार फंक को वर्तमान द्वारा बुलाया जाता है aN*base**N

आधार% (आधार -1) == 1 आधार आधार ** पी% (आधार -1) == 1 और उसके बाद q * आधार ^ p% (आधार -1) == q केवल एक अपवाद के साथ जब q = आधार -1 जो 0 लौटाता है। उस स्थिति में इसे ठीक करने के लिए 0 कवक जाँच कर रहा है, क्या यह भिखारी से 0 है।


फायदे

इस नमूने में केवल एक गुणन (विभाजन के बजाय) और कुछ मौदुलेसिस होते हैं जो अपेक्षाकृत कम समय लेते हैं।


1
num = input("number")
power = 0
num = int(num)
while num > 10:
    num = num / 10
    power += 1

print(str(round(num, 2)) + "^" + str(power))

कृपया कुछ संक्षिप्त जानकारी जोड़ें कि आपने क्या किया था
फरहाना

हालांकि यह लेखकों के सवाल का जवाब दे सकता है, लेकिन इसमें कुछ स्पष्ट शब्दों और / या प्रलेखन के लिंक का अभाव है। रॉ कोड स्निपेट अपने आसपास के कुछ वाक्यांशों के बिना बहुत मददगार नहीं हैं। आपको यह भी पता चल सकता है कि एक अच्छा उत्तर बहुत उपयोगी कैसे लिखें । कृपया अपना उत्तर संपादित करें।
नरक

1
def base_changer(number,base):
    buff=97+abs(base-10)
    dic={};buff2='';buff3=10
    for i in range(97,buff+1):
        dic[buff3]=chr(i)
        buff3+=1   
    while(number>=base):
        mod=int(number%base)
        number=int(number//base)
        if (mod) in dic.keys():
            buff2+=dic[mod]
            continue
        buff2+=str(mod)
    if (number) in dic.keys():
        buff2+=dic[number]
    else:
        buff2+=str(number)

    return buff2[::-1]   

इस फ़ंक्शन में आप आसानी से किसी भी दशमलव संख्या को अपने पसंदीदा आधार में बदल सकते हैं।
मोंटाकामी

आपको अपने स्वयं के उत्तर की आवश्यकता नहीं है, आप स्पष्टीकरण जोड़ने के लिए इसे संपादित कर सकते हैं।
पोचमर्निक 18

1

यहां किसी भी आधार की संख्या को दूसरे आधार में परिवर्तित करने का एक उदाहरण दिया गया है।

from collections import namedtuple

Test = namedtuple("Test", ["n", "from_base", "to_base", "expected"])


def convert(n: int, from_base: int, to_base: int) -> int:
    digits = []
    while n:
        (n, r) = divmod(n, to_base)
        digits.append(r)    
    return sum(from_base ** i * v for i, v in enumerate(digits))


if __name__ == "__main__":
    tests = [
        Test(32, 16, 10, 50),
        Test(32, 20, 10, 62),
        Test(1010, 2, 10, 10),
        Test(8, 10, 8, 10),
        Test(150, 100, 1000, 150),
        Test(1500, 100, 10, 1050000),
    ]

    for test in tests:
        result = convert(*test[:-1])
        assert result == test.expected, f"{test=}, {result=}"
    print("PASSED!!!")

0
def dec_to_radix(input, to_radix=2, power=None):
    if not isinstance(input, int):
        raise TypeError('Not an integer!')
    elif power is None:
        power = 1

    if input == 0:
        return 0
    else:
        remainder = input % to_radix**power
        digit = str(int(remainder/to_radix**(power-1)))
        return int(str(dec_to_radix(input-remainder, to_radix, power+1)) + digit)

def radix_to_dec(input, from_radix):
    if not isinstance(input, int):
        raise TypeError('Not an integer!')
    return sum(int(digit)*(from_radix**power) for power, digit in enumerate(str(input)[::-1]))

def radix_to_radix(input, from_radix=10, to_radix=2, power=None):
    dec = radix_to_dec(input, from_radix)
    return dec_to_radix(dec, to_radix, power)

0

एक और छोटा एक (और समझने के लिए आसान imo):

def int_to_str(n, b, symbols='0123456789abcdefghijklmnopqrstuvwxyz'):
    return (int_to_str(n/b, b, symbols) if n >= b else "") + symbols[n%b]

और उचित अपवाद हैंडलिंग के साथ:

def int_to_str(n, b, symbols='0123456789abcdefghijklmnopqrstuvwxyz'):
    try:
        return (int_to_str(n/b, b) if n >= b else "") + symbols[n%b]
    except IndexError:
        raise ValueError(
            "The symbols provided are not enough to represent this number in "
            "this base")

0

एक और समाधान, बेस 2 से 10 के साथ काम करता है, उच्च आधार के लिए संशोधन की आवश्यकता है:

def n2b(n, b):
    if n == 0:
        return 0
    d = []
    while n:
        d.append(int(n % b))
        n /= b
    return ''.join(map(str,d[::-1]))

उदाहरण:

n2b(10,2) => '10100'
int(n2b(10,2),2) => 10

0

यहाँ एक पुनरावर्ती संस्करण है जो हस्ताक्षरित पूर्णांक और कस्टम अंक संभालता है।

import string

def base_convert(x, base, digits=None):
    """Convert integer `x` from base 10 to base `base` using `digits` characters as digits.
    If `digits` is omitted, it will use decimal digits + lowercase letters + uppercase letters.
    """
    digits = digits or (string.digits + string.ascii_letters)
    assert 2 <= base <= len(digits), "Unsupported base: {}".format(base)
    if x == 0:
        return digits[0]
    sign = '-' if x < 0 else ''
    x = abs(x)
    first_digits = base_convert(x // base, base, digits).lstrip(digits[0])
    return sign + first_digits + digits[x % base]

0

संख्याओं का प्रतिनिधित्व करने के लिए स्ट्रिंग्स एकमात्र विकल्प नहीं हैं: आप प्रत्येक अंक के आदेश का प्रतिनिधित्व करने के लिए पूर्णांकों की सूची का उपयोग कर सकते हैं। जिन्हें आसानी से स्ट्रिंग में बदला जा सकता है।

कोई भी उत्तर आधार को अस्वीकार नहीं करता है <2; और अधिकांश बहुत धीमी गति से चलेगा या बहुत बड़ी संख्या (जैसे 56789 ** 43210) के लिए स्टैक ओवरफ्लो के साथ दुर्घटनाग्रस्त होगा । ऐसी विफलताओं से बचने के लिए, जल्दी से इस तरह कम करें:

def n_to_base(n, b):
    if b < 2: raise # invalid base
    if abs(n) < b: return [n]
    ret = [y for d in n_to_base(n, b*b) for y in divmod(d, b)]
    return ret[1:] if ret[0] == 0 else ret # remove leading zeros

def base_to_n(v, b):
    h = len(v) // 2
    if h == 0: return v[0]
    return base_to_n(v[:-h], b) * (b**h) + base_to_n(v[-h:], b)

assert ''.join(['0123456789'[x] for x in n_to_base(56789**43210,10)])==str(56789**43210)

स्पीडवाइज़, बड़ी संख्या (मेरी मशीन पर लगभग 0.3s) के n_to_baseसाथ तुलनीय है str, लेकिन अगर आप तुलना करते हैंhex हैं आश्चर्यचकित हो सकते हैं (मेरी मशीन पर लगभग 0.3ms, या 1000x तेज़)। इसका कारण यह है कि बड़े पूर्णांक को स्मृति में आधार 256 (बाइट्स) में संग्रहीत किया जाता है। प्रत्येक बाइट को केवल दो-वर्ण हेक्स स्ट्रिंग में परिवर्तित किया जा सकता है। यह संरेखण केवल उन ठिकानों के लिए होता है जो दो की शक्तियां हैं, यही वजह है कि 2,8, और 16 (और बेस 64, एससीआई, यूटी 16, यूएफ 32) के लिए विशेष मामले हैं।

दशमलव स्ट्रिंग के अंतिम अंक पर विचार करें। यह बाइट्स के अनुक्रम से कैसे संबंधित है जो इसका पूर्णांक बनाता है? चलो कम से कम महत्वपूर्ण (थोड़ा एंडियन) होने के s[i]साथ बाइट्स लेबल करें s[0]। फिर पिछले अंक है sum([s[i]*(256**i) % 10 for i in range(n)])। ठीक है, ऐसा होता है कि 256 ** i 6 के लिए i> 0 (6 * 6 = 36) के साथ समाप्त होता है ताकि अंतिम अंक हो (s[0]*5 + sum(s)*6)%10। इससे, आप देख सकते हैं कि अंतिम अंक सभी बाइट्स के योग पर निर्भर करता है। यह गैर-संपत्ति संपत्ति है जो दशमलव को कठिन रूप में परिवर्तित करती है।


0
def baseConverter(x, b):
    s = ""
    d = string.printable.upper()
    while x > 0:
        s += d[x%b]
        x = x / b
    return s[::-1]

Python3 के लिए आपका कोड ऐसा करता है: baseConverter (0, 26) -> 'baseConverter (1, 26) ->' 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001 'के लिए यह python2 करता है: baseConverter (0, 26, 26) -> 1 बेसकॉन्सर (3, 26) -> 3 बेसकॉन्सेसर (5, 26) -> 5 बेसकॉन्सेसर (26, 26) -> 10 बेसकॉन्सर (32, 26) -> 16
ड्रेचनफेल्टर

0

वैसे मैं व्यक्तिगत रूप से इस फ़ंक्शन का उपयोग करता हूं, मेरे द्वारा लिखा गया है

import string

def to_base(value, base, digits=string.digits+string.ascii_letters):    # converts decimal to base n

    digits_slice = digits[0:base]

    temporary_var = value
    data = [temporary_var]

    while True:
        temporary_var = temporary_var // base
        data.append(temporary_var)
        if temporary_var < base:
            break

    result = ''
    for each_data in data:
        result += digits_slice[each_data % base]
    result = result[::-1]

    return result

यह आप इसका उपयोग कैसे कर सकते हैं

print(to_base(7, base=2))

आउटपुट: "111"

print(to_base(23, base=3))

आउटपुट: "212"

कृपया मेरे कोड में सुधार का सुझाव देने के लिए स्वतंत्र महसूस करें।


0
def base_conversion(num, base):
    digits = []
    while num > 0:
        num, remainder = divmod(num, base)
        digits.append(remainder)
    return digits[::-1]

0

यह एक पुराना सवाल है, लेकिन मुझे लगा कि मैं इस पर अपना हिस्सा साझा करूंगा क्योंकि मुझे लगता है कि यह कुछ हद तक सरल है कि अन्य उत्तर (2 से 36 के लिए आधारों के लिए अच्छा है):

def intStr(n,base=10):
    if n < 0   : return "-" + intStr(-n,base)         # handle negatives
    if n < base: return chr([48,55][n>9] + n)         # 48 => "0"..., 65 => "A"...
    return intStr(n//base,base) + intStr(n%base,base) # recurse for multiple digits

-1

मैंने यहां फ्लोट के किसी भी कन्वर्टर्स को नहीं देखा है। और मैं हमेशा तीन अंकों के लिए समूह बनाने से चूक गया।

करने के लिए:

वैज्ञानिक अभिव्यक्ति में बोझ (n.nnnnnn*10**(exp)- '10'हैself.baseDigits[1::-1]/self.to_string(len (self.baseDigits))

-from_string-कार्य करते हैं।

-बेस 1 -> रोमेन नंबर?

-आगलों के साथ जटिल की

तो यहाँ मेरा समाधान है:

DIGITS = "0123456789abcdefghijklmnopqrstuvwxyz"


# note that the order of the digits is reversed for digits before the point
NO_GROUPING = lambda g: g

concat = "".join
concat_backwards = lambda g: concat(e for e in reversed(list(g)))

def grouping(length = 3, char = '_'):
    def yieldor(digits):
        i = 0
        for d in digits:
            if i == length:
                yield char
                i = 0
            yield d
            i+=1

    return yieldor

class Converter:
    def __init__(self, baseDigits: (int, str), beforePoint = NO_GROUPING, afterPoint = NO_GROUPING, decimalPoint = '.', digitPrecision = 16, trimZeros = True):
        if isinstance(baseDigits, int):
            baseDigits = DIGITS[:baseDigits]
        self.baseDigits = baseDigits

        self.beforePoint = beforePoint
        self.afterPoint  = afterPoint

        self.decimalPoint = decimalPoint
        self.digitPrecision = digitPrecision
        self.trimZeros = trimZeros

    def to_string(self, number: (int, float, complex)) -> str:
        if isinstance(number, complex):
            if number.imag == 0:
                return self.to_string(number.real)
            if number.real == 0:
                return self.to_string(number.imag) + 'j'
            return "({}+{}j)".format(self.to_string(number.real), self.to_string (number.imag))
        if number < 0:
            return '-' + self.to_string(-number)
        digitCount = len(self.baseDigits)
        if isinstance(number, float):
            # round correctly
            precError=digitCount**-self.digitPrecision
            number+=0.5*precError
            if self.trimZeros:
                def yieldor(n):
                    p = precError
                    for i in range(self.digitPrecision):
                        if n <= p:
                            return
                        p *= digitCount
                        n *= digitCount
                        digit = int(n)
                        n -= digit
                        yield self.baseDigits[digit]
            else:
                def yieldor(n):
                    for i in range(self.digitPrecision):
                        n *= digitCount
                        digit = int(n)
                        n -= digit
                        yield self.baseDigits[digit]

            a = concat(self.afterPoint(yieldor(number%1)))

            return (
                self.to_string(int(number)) + (a and self.decimalPoint + a)
            )

        else: #is int
            if not number: return self.baseDigits[0]
            def yieldor(n):
                while n:
                    n, digit = divmod(n, digitCount)
                    yield self.baseDigits[digit]
            return concat_backwards(self.beforePoint(yieldor(number)))

# some tests:
if __name__ == "__main__":
    def conv_test(num, digits, *argv, **kwv):
        print(num, "->", digits if isinstance(digits, int) else "{} ({})".format(len(digits), digits), Converter(digits, *argv, **kwv).to_string(num))
    conv_test(True, "ft")
    conv_test(123, 12, grouping(2))
    conv_test(-0xf00d, 16)
    conv_test(1000, True<<True, grouping(4))
    conv_test(1_000_000, "0+-", beforePoint = grouping(2, '|'))
    conv_test(1.5, 10)
    conv_test(0.999999999, 10, digitPrecision = 8)
    conv_test(-0.1, 10)

    import math
    conv_test(math.pi, 10, afterPoint = grouping(5, ' '))
    conv_test(0.123456789, 10, digitPrecision = 6)

    grSpc = grouping(1, ' ')
    conv_test(math.e, ["off", "on"], grSpc, grSpc, " dot ", digitPrecision = 7)

    conv_test(1 + 1.5j, 10)

    conv_test(50j, 10)

    conv_test(10.01, '-<>')

    # and generate some brainfuck-code here:
    conv_test(1701**42, '+-<>,.][', digitPrecision = 32)

-2
def bn(x,b,ab="0123456789abcdefghijklmnopqrstuvwxyz..."
    a = ""
    while (x>0):
        x,r = divmod(x,n)
        a += ab[r]
    return a[::-1]

bn(2**100, 36)

उत्पादन:

3ewfdnca0n6ld1ggvfgg

किसी भी आधार में बदलने के लिए, उलटा भी आसान है।


मिल गया NameError: global name 'n' is not defined। है divmod(x, n)होना चाहिए divmod(x, b)?
वेजेंड्रिया
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.