Toán học đằng sau việc chuyển đổi từ cơ sở nào sang cơ sở nào mà không qua cơ sở 10?


35

Tôi đã xem xét toán học đằng sau việc chuyển đổi từ bất kỳ cơ sở nào sang bất kỳ cơ sở nào. Đây là nhiều hơn về việc xác nhận kết quả của tôi hơn bất cứ điều gì. Tôi đã tìm thấy những gì dường như là câu trả lời của tôi trên mathforum.org nhưng tôi vẫn không chắc liệu mình có đúng không. Tôi có việc chuyển đổi từ cơ sở lớn hơn sang cơ sở nhỏ hơn được rồi vì đơn giản chỉ cần lấy chữ số đầu tiên nhân với cơ sở bạn muốn thêm lặp lại chữ số tiếp theo. Vấn đề của tôi xuất hiện khi chuyển đổi từ cơ sở nhỏ hơn sang cơ sở lớn hơn. Khi làm điều này họ nói về cách bạn cần chuyển đổi cơ sở lớn hơn mà bạn muốn thành cơ sở nhỏ hơn mà bạn có. Một ví dụ sẽ là từ cơ sở 4 sang cơ sở 6, bạn cần chuyển đổi số 6 thành cơ sở 4 nhận được 12. Sau đó, bạn chỉ cần làm điều tương tự như khi bạn chuyển đổi từ lớn sang nhỏ. Khó khăn của tôi với điều này là có vẻ như bạn cần biết một số trong cơ sở khác là gì. Vì vậy, tôi cần phải biết 6 là gì trong cơ sở 4. Điều này tạo ra một vấn đề lớn trong tâm trí của tôi bởi vì sau đó tôi sẽ cần một bảng. Có ai biết một cách để làm điều này trong một thời trang tốt hơn.

Tôi nghĩ rằng một chuyển đổi cơ sở sẽ giúp nhưng tôi không thể tìm thấy bất kỳ công việc đó. Và từ trang web tôi thấy có vẻ như cho phép bạn chuyển đổi từ cơ sở sang cơ sở mà không cần thông qua cơ sở 10 nhưng trước tiên bạn cần biết cách chuyển đổi số đầu tiên từ cơ sở sang cơ sở. Điều đó làm cho nó trở nên vô nghĩa.

Các nhà bình luận đang nói rằng tôi cần có khả năng chuyển đổi một chữ cái thành một số. Nếu vậy tôi đã biết điều đó. Đó không phải là vấn đề của tôi. Vấn đề của tôi là để chuyển đổi một cơ sở lớn thành một cơ sở nhỏ, trước tiên tôi cần chuyển đổi số cơ sở tôi có thành số cơ sở tôi muốn. Khi làm điều này, tôi đánh bại mục đích bởi vì nếu tôi có khả năng chuyển đổi các căn cứ này sang các căn cứ khác thì tôi đã giải quyết được vấn đề của mình.

Chỉnh sửa: Tôi đã tìm ra cách chuyển đổi từ các cơ sở nhỏ hơn hoặc bằng 10 thành các cơ sở khác nhỏ hơn hoặc bằng 10. Tôi cũng có thể đi từ một cơ sở lớn hơn 10 đến bất kỳ cơ sở nào có giá trị từ 10 trở xuống. Vấn đề bắt đầu khi chuyển đổi từ một cơ sở lớn hơn 10 sang một cơ sở khác lớn hơn 10. Hoặc đi từ một cơ sở nhỏ hơn 10 đến một cơ sở lớn hơn 10. Tôi không cần mã Tôi chỉ cần toán học cơ bản đằng sau nó có thể áp dụng cho mã.


1
Là câu hỏi về chủ đề cho diễn đàn này?
Andrej Bauer

2
Quy trình này không quan trọng miễn là bạn có thể thực hiện phép cộng và nhân trong cơ sở đích. Nếu bạn không thể, tôi không nghĩ rằng nó có thể.
Karolis Juodelė

9
Trước tiên, Griffin nên được cho biết những gì nhiều sinh viên cần nghe: những con số tồn tại mà không được thể hiện trong một căn cứ . Sau đó, câu trả lời đã rõ ràng: chúng ta cần các thuật toán, một để hội tụ một đại diện của một số trong một cơ sở nhất định cho số đó (nghĩa là, một cái gì đó lấy stringvà trả về một int), và một thuật toán lấy một số và trả về đại diện của nó trong một cơ sở nhất định.
Andrej Bauer

1
@AndrejBauer Câu hỏi là về CS: ngay cả khi nó không được diễn đạt theo cách đó, đây là câu hỏi về thuật toán để chuyển đổi giữa các biểu diễn số. [Ghi chú không liên quan: Tôi đã xóa một loạt các bình luận khó hiểu. Griffin: vui lòng chỉnh sửa câu hỏi của bạn để cập nhật nó. Những người khác: vui lòng mang nó đi trò chuyện .]
Gilles 'SO- ngừng trở nên xấu xa'

1
@Griffin đã lâu rồi kể từ câu hỏi ban đầu của bạn. Tôi hy vọng bạn đã tìm thấy câu trả lời của bạn. Nếu vậy có lẽ đó là một ý tưởng tuyệt vời để cập nhật và chấp nhận câu trả lời hoặc đăng bài của bạn. Trong thời gian đó, tôi đã tìm thấy một vài ý tưởng rất hay (nói về việc triển khai trong C ++) trong Lưu trữ Mã Jam của Google. Một số giải pháp cho vấn đề này là rất sáng tạo code.google.com/codejam/contest/32003/dashboard
IsaacCisneros

Câu trả lời:


45

Đây có vẻ là một câu hỏi rất cơ bản đối với tôi, vì vậy xin lỗi nếu tôi giảng cho bạn một chút. Điểm quan trọng nhất để bạn tìm hiểu ở đây là một số không phải là biểu diễn chữ số của nó . Một số là một đối tượng toán học trừu tượng, trong khi biểu diễn chữ số của nó là một thứ cụ thể, cụ thể là một chuỗi các ký hiệu trên một tờ giấy (hoặc một chuỗi các bit trong bộ nhớ tính toán, hoặc một chuỗi các âm thanh mà bạn tạo ra khi bạn giao tiếp một số). Điều làm bạn bối rối là thực tế là bạn không bao giờ nhìn thấy một con số mà luôn luôn đại diện cho chữ số của nó. Vì vậy, cuối cùng bạn nghĩ rằng con số đại diện.

Do đó, câu hỏi chính xác cần đặt ra không phải là "làm thế nào để tôi chuyển đổi từ cơ sở này sang cơ sở khác" mà là "làm thế nào để tôi tìm ra số nào được biểu thị bằng một chuỗi chữ số đã cho" và "làm cách nào để tìm đại diện chữ số của a số đã cho ".

Vì vậy, chúng ta hãy tạo ra hai hàm trong Python, một hàm để chuyển đổi biểu diễn chữ số thành số và một hàm khác để làm ngược lại. Lưu ý: khi chúng tôi chạy chức năng Python tất nhiên sẽ in trên màn hình số nó có trong cơ sở 10. Nhưng điều này không có nghĩa là máy tính đang giữ số ở cơ sở 10 (không phải vậy). Nó không liên quan như thế nào máy tính đại diện cho các con số.

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

Hãy để chúng tôi kiểm tra những điều này:

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

Được trang bị các chức năng chuyển đổi, vấn đề của bạn được giải quyết dễ dàng:

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

Một thử nghiệm:

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

Lưu ý: chúng tôi đã không thông qua đại diện cơ sở 10! Chúng tôi đã chuyển đổi đại diện cơ sở thành số, và sau đó số thành cơ sở c . Con số không có trong bất kỳ đại diện. (Trên thực tế, máy tính phải đại diện cho nó bằng cách nào đó và nó đã đại diện cho nó bằng cách sử dụng tín hiệu điện và những thứ thú vị xảy ra trong chip, nhưng chắc chắn đó không phải là 0 và 1.)bc


4
Điều này không thuyết phục tôi 100%. Trong thực tế, bạn đã chuyển đổi số thành một số biểu diễn (mặc dù bạn có thể tuyên bố không biết nó là gì) bởi vì máy tính không phải là nhà toán học thuần túy và thuật toán của bạn không thể chuyển đổi một chuỗi các chữ số tùy ý trong cơ sở sang cơ sở b 2 ; nó chỉ có thể chuyển đổi trình tự đại diện bởi máy bê tông. Python linh hoạt quyến rũ; C sẽ không được tha thứ như vậy. Hoàn toàn hợp lệ khi hỏi cách chuyển đổi các chuỗi tùy ý từ b 1 sang b 2 ; tuy nhiên, điều này chỉ có thể trong thời gian tuyến tính ngoại trừ với các kết hợp cơ sở nhất định (ví dụ: 2 <-> 16)b1b2b1b2
rici

1
Nó là hợp lệ để đặt câu hỏi, nhưng để tìm câu trả lời đúng, tốt nhất là nhận thức được thực tế rằng các con số là các thực thể trừu tượng.
Andrej Bauer

2
Điều này không vượt qua số thông qua đại diện cơ sở 10, vì fromDigitstrả về số trong cơ sở 10.
apnorton

8
@anorton: Không, chắc chắn là không . Python in số trên màn hình dưới dạng đại diện 10 chữ số cơ bản, nhưng bản thân số đó không được lưu theo cách đó. Những gì tôi đang cố gắng để hiểu được là nó không liên quan đến cách các con số được thực hiện bên trong Python. Không quan trọng. Điều duy nhất quan trọng là họ cư xử như những con số.
Andrej Bauer

3
Cuối cùng, một giải pháp chung cho bất kỳ cơ sở nào và không giới hạn trong các trường hợp sử dụng cụ thể, các cơ sở nhỏ hơn 36 hoặc các trường hợp mà bạn có thể đưa ra đủ các ký hiệu duy nhất.
J.Money

21

Tôi nghĩ rằng cách tốt nhất để hiểu điều này là trong cuộc thảo luận với người ngoài hành tinh (ít nhất là tương tự).

Định nghĩa là một số trong cơ sở bxb có nghĩa là là một chuỗi các chữ số < b .x<b

Ví dụ Chuỗi các chữ số 10010011011 là một số trong cơ sở 2, chuỗi 68416841531 là một số trong cơ sở 10, BADCAFE là một số trong cơ sở 16.

Bây giờ Giả sử tôi lớn lên trên hành tinh quux nơi tất cả mọi người được dạy để làm việc tại cho toàn bộ cuộc sống của họ, và tôi gặp bạn của những người được sử dụng để cơ sở b . Vì vậy, bạn chỉ cho tôi một số, và tôi phải làm gì? Tôi cần một cách để giải thích nó:qb

Định nghĩa Tôi có thể diễn giải một số trong cơ sở (Lưu ý: b là một số trong cơ sở q ) theo công thức saubbq

[[ϵ]]=0[[s¯d]]=[[s¯]]×b+d

nơi biểu thị chuỗi rỗng, và ˉ s d biểu thị một chuỗi kết thúc bằng các chữ số d . Xem bằng chứng của tôi rằng bổ sung thêmϵs¯dd cho một giới thiệu về ký hiệu này.

Vậy chuyện gì đã xảy ra ở đây? Bạn đã cho tôi một số ở cơ sở và tôi đã giải thích nó thành cơ sở q mà không có bất kỳ triết lý kỳ lạ nào về những con số thực sự là gì.bq

Chìa khóa Chìa khóa cho điều này là + Tôi có các hàm hoạt động trên các số q cơ sở . Đây là các thuật toán đơn giản được định nghĩa đệ quy trên các số q cơ sở (chuỗi các chữ số).×+qq


Điều này có vẻ hơi trừu tượng vì tôi đã sử dụng các biến thay vì số thực tế trong suốt. Vì vậy, chúng ta hãy giả sử bạn là một sinh vật cơ sở 13 (sử dụng những biểu tượng ) và tôi đã quen với cơ sở 7 (mà là nhiều hơn nữa hợp lý) sử dụng những biểu tượng alpha beta gamma delta ρ ζ ξ .0123456789XYZαβγδρζξ

Vì vậy, tôi đã thấy bảng chữ cái của bạn và lập bảng như vậy:

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

βξ

60Z8

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

Vì vậy, tôi bắt đầu bằng cách nhân ra nhưng đây là công cụ học lớp cho tôi, tôi nhớ lại:βζ×βξ

Bảng nhân Quux

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

βζ×βξ

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

vì vậy tôi đã có được điều này đến nay

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

Bây giờ tôi cần thực hiện bổ sung bằng thuật toán đã được đề cập trước đó:

δβγββδγδ

vì thế

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

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

qbq


1
Vâng, đó là một thỏa thuận tốt của dòng nguệch ngoạc. Làm thế nào tôi có được máy tính để làm điều đó mặc dù?
Griffin

1
@Griffin, tôi nghĩ bạn đang hỏi câu hỏi đó (lạ) sớm. Bạn chọn một ngôn ngữ lập trình và nhập thuật toán để cộng và nhân trên các số q cơ sở (được biểu diễn dưới dạng danh sách các chữ số), sau đó xác định hàm để diễn giải các chữ số b cơ sở thành số q cơ sở và giải thích các số b cơ sở thành số q cơ sở. Tôi đã giải thích tất cả điều này.

Điều tôi biết là bạn đang cố gắng miêu tả. Vấn đề của tôi là máy tính của tôi không thể sử dụng các dòng nguệch ngoạc của bạn.
Griffin

Tôi biết những gì bạn đã giải thích nhưng đưa nó vào thực tế là khó khăn hơn nhiều. Bạn thấy việc xác định những chữ số đó không dễ dàng.
Griffin

1
Ngoài ra tại sao bạn thả chữ số alpha ở vị trí quan trọng nhất? Vì 6 = & xi;, Sẽ không 7 = & alpha; & alpha;?
Giovanni Botta

9

Đây chỉ là một cấu trúc lại (Python 3) mã của Andrej . Trong số mã của Andrej được thể hiện thông qua một danh sách các chữ số (vô hướng), trong khi các mã số sau đây được thể hiện thông qua một danh sách các ký hiệu được lấy từ một chuỗi tùy chỉnh :

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)

Để thực hiện chuyển đổi từ giá trị sang biểu diễn trong cơ sở tùy chỉnh:

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

Để thực hiện chuyển đổi từ đại diện (trong cơ sở tùy chỉnh) sang giá trị:

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

Để thực hiện chuyển đổi cơ sở từ cơ sở này sang cơ sở khác:

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

1
Chào mừng đến với trang web và cảm ơn sự đóng góp của bạn. Tuy nhiên, việc tạo mã nguồn được tối ưu hóa tốt không phải là những gì trang web này thực sự hướng tới. Mã của Andrej làm cho các khái niệm rõ ràng, đó là điều cần thiết cho câu trả lời của anh ta, nhưng cải thiện mã vượt ra ngoài đó là vấn đề lập trình, thay vì khoa học máy tính .
David Richerby

1
@DavidR Richby Tôi đồng ý một phần, nhưng đóng góp này quá dài cho một bình luận và vị trí tốt nhất của nó là ở đâu đó gần câu trả lời của Andrej, đó là lý do tại sao tôi đăng nó ở đây. Dù sao, nếu bạn nghĩ rằng tốt hơn tôi có thể chuyển đổi nó thành một nhận xét với một liên kết đến mã, nhưng nó sẽ không phải là quá mức của chủ nghĩa thuần túy?
mmj

1

Hoạt động cơ bản của hội tụ cơ sở là toDigits()hoạt động của câu trả lời @AndrejBauer. Tuy nhiên, để làm cho nó không cần phải tạo một số trong biểu diễn bên trong của các số, về cơ bản là một chuyển đổi từ và đại diện cho cơ sở 2. Bạn có thể thực hiện các hoạt động cần thiết trong đại diện cơ sở ban đầu.

Vì vậy, bước đầu tiên là thực hiện thao tác phân chia modulo lặp đi lặp lại

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

Vì biểu diễn bên trong là các chữ số, người ta phải tạo một hàm được xác định để kiểm tra zero

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

Cuối cùng, người ta phải thực hiện thao tác modulo_div, đây thực sự là sự phân chia tiêu chuẩn theo cơ sở đích như chúng ta đã học ở trường.

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

chỉ cần kiểm tra để xác minh mã là chính xác:

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]

Cảm ơn bạn đã đăng bài nhưng xin lưu ý rằng chúng tôi không phải là một trang web mã hóa, vì vậy một khối lớn mã không phù hợp như một câu trả lời ở đây. Đặc biệt là khi câu hỏi nói rõ ràng: "Tôi không cần mã, tôi chỉ cần toán cơ bản đằng sau nó."
David Richerby

@DavidR Richby Tôi đã cố gắng thêm văn bản.
Xavier Combelle

Cảm ơn. Và tôi thấy có rất nhiều mã trên trang này, bất chấp những gì tôi nói!
David Richerby

0

Tôi biết một cách dễ dàng để thực hiện chuyển đổi cơ sở mà không yêu cầu chương trình máy tính. Đó là bằng cách xác định một cách để chuyển đổi từ bất kỳ cơ sở nào sang cơ sở 2 và ngược lại và sau đó chuyển đổi từ cơ sở này sang cơ sở khác bằng cách chuyển đổi từ cơ sở đầu tiên sang cơ sở 2 sau đó chuyển đổi từ cơ sở 2 sang cơ sở khác. 2 rất dễ dàng để nhân hoặc chia trong bất kỳ cơ sở.

Để chuyển đổi từ bất kỳ cơ sở nào sang cơ sở 2, tất cả những gì bạn phải làm là nhận ra rằng với bất kỳ số nào, nếu bạn lấy ký hiệu cơ sở 2 của nó và bắt đầu từ 0 và sau đó cho mỗi chữ số theo thứ tự từ trái sang phải gấp đôi nếu chữ số đó bằng 0 và gấp đôi thêm 1 nếu chữ số đó là 1, bạn sẽ nhận được chính số đó. Bây giờ với số đó trong bất kỳ cơ sở nào, bạn có thể chia cho 2 trong cơ sở đó để lấy thương số và phần còn lại. Nếu phần còn lại là 1, chữ số nhị phân cuối cùng là 1 và nếu phần còn lại là 0, chữ số nhị phân cuối cùng là 0. Chia cho 2 lần nữa. Nếu phần còn lại là 1, chữ số cuối cùng thứ hai là 1 và nếu phần còn lại là 0, chữ số cuối cùng thứ hai là 0 và cứ thế cho đến khi bạn nhận được thương số là 0.

Để chuyển đổi từ cơ sở 2 sang bất kỳ cơ sở nào, tất cả những gì bạn phải làm là ở cơ sở đó, bắt đầu từ 0, sau đó cho mỗi chữ số nhị phân đi từ trái sang phải, tăng gấp đôi trong cơ sở đó nếu chữ số đó là 0 và gấp đôi sau đó thêm 1 vào đó cơ sở nếu chữ số đó là 1.


2 is so easy to multiply or divide by in any base.Tôi không thấy rằng đối với các căn cứ kỳ lạ có nhiều hơn một từ bất kỳ sức mạnh nào của hai (11 và 13, để bắt đầu).
greybeard

0

Bạn có thể chuyển đổi từ cơ sở n sang cơ sở 10 mà không cần chuyển đổi sang một số cơ sở trung gian.

Ví dụ, để chuyển đổi từ cơ sở n sang cơ sở 9, bạn sử dụng thuật toán để chuyển đổi sang cơ sở 10 và thay thế 10 phút 10 bằng Thay đổi 9. Tương tự cho bất kỳ cơ sở khác.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.