베이스 10을 거치지 않고베이스를베이스로 변환하는 수학은 무엇입니까?


35

나는 어떤 기초에서 어떤 기초로 변환하는 것에 대한 수학을 조사해 왔습니다. 이것은 무엇보다 내 결과를 확인하는 것입니다. mathforum.org에서 내 답변으로 보이는 것을 찾았지만 여전히 올바른지 확실하지 않습니다. 큰 숫자에서 작은 숫자로 변환하는 것이 좋습니다. 왜냐하면 단순히 첫 자릿수를 기본 숫자로 곱하기 때문에 다음 자릿수 반복을 추가하고 싶습니다. 작은베이스에서 더 큰베이스로 변환 할 때 문제가 발생합니다. 이 작업을 수행 할 때 원하는 더 큰베이스를 더 작은베이스로 변환하는 방법에 대해 설명합니다. 예를 들어 밑 4에서 밑 6으로 가려면 숫자 6을 밑 4를 12로 바꾸면됩니다. 그러면 큰 것에서 작은 것으로 바꿀 때와 똑같은 일을합니다. 내가 가진 어려움은 한 숫자가 다른 숫자에 무엇인지 알아야한다는 것입니다. 그래서 6이 4에 무엇인지 알아야 할 필요가 있습니다. 테이블이 필요하기 때문에 마음에 큰 문제가 생깁니다. 더 나은 방법으로 이것을하는 방법을 아는 사람이 있습니까?

기본 전환이 도움이 될 것이라고 생각했지만 해당 작업을 찾을 수 없습니다. 그리고 사이트에서 10을 거치지 않고 기본에서 기본으로 변환 할 수있는 것처럼 보이지만 먼저 첫 번째 숫자를 기본에서 기본으로 변환하는 방법을 알아야합니다. 그것은 무의미합니다.

주석가들은 문자를 숫자로 변환 할 수 있어야한다고 말합니다. 그렇다면 이미 알고 있습니다. 그러나 그것은 내 문제가 아닙니다. 내 문제는 큰 염기를 작은 염기로 변환하기 위해 먼저 내가 가지고있는 기본 번호를 원하는 기본 번호로 변환해야한다는 것입니다. 이 작업을 수행 할 때 이러한 기본을 다른 기본으로 변환 할 수 있으면 이미 문제를 해결했기 때문에 목적을 무효화합니다.

편집 : 10 이하의 기지에서 10 이하의 다른 기지로 변환하는 방법을 알아 냈습니다. 또한 10보다 큰 기지에서 10 이하의 기지로 갈 수 있습니다. 문제는 10보다 큰 기본에서 10보다 큰 다른 기본으로 변환 할 때 시작됩니다. 또는 10보다 작은 기본에서 10보다 큰 기본으로 이동하면 코드가 필요하지 않습니다. 코드가 필요하지 않습니다. 코드에 적용됩니다.


1
이 포럼의 주제에 대한 질문입니까?
Andrej Bauer

2
대상베이스에서 더하기 및 곱하기를 수행 할 수있는 한 절차는 간단합니다. 당신이 할 수 없다면, 나는 그것이 가능하지 않다고 생각합니다.
Karolis Juodelė

9
그리핀은 먼저 많은 학생들이들을 필요가있는 것을들을 있어야합니다 . 그 대답은 분명합니다. 우리 는 주어진 염기의 숫자 표현 을 숫자로 수렴하기위한 알고리즘 (a를 가져 와서 string반환하는 것 int)과 숫자를 가져 와서 표현을 반환하는 알고리즘이 필요합니다 주어진 기지에서.
Andrej Bauer

1
@AndrejBauer 질문은 CS에 관한 것입니다. 그런 식으로 말하지 않더라도 이것은 숫자 표현 사이를 변환하는 알고리즘에 관한 질문입니다. [관련되지 않은 메모 : 혼란스러운 댓글을 많이 삭제했습니다. 그리핀 : 질문을 편집하여 업데이트하십시오. 기타 : 채팅을 해주세요 .]
Gilles 'SO- 악의를 그만두십시오'

1
@Griffin 원래 질문 이후 오랜 시간이 지났습니다. 답을 찾길 바랍니다. 그렇다면 답변을 업데이트하고 수락하거나 답변을 게시하는 것이 좋습니다. 그 동안 Google의 Code Jam Archives에서 몇 가지 훌륭한 아이디어 (C ++ 구현에 대해 이야기)를 발견했습니다. 이 문제에 대한 해결책은 매우 창의적인 code.google.com/codejam/contest/32003/dashboard입니다.
IsaacCisneros

답변:


45

이것은 나에게 매우 기본적인 질문으로 보입니다. 조금만 강의하면 실례합니다. 여기서 배울 점 은 숫자가 숫자가 아니라는 것 입니다. 숫자는 추상적 인 수학적 객체 인 반면 숫자 표현은 구체적인 것, 즉 종이의 일련의 심볼 (또는 계산 메모리의 일련의 비트 또는 숫자를 전달할 때 만드는 일련의 사운드)입니다. 당신을 혼란하면 결코 사실입니다 수 있지만, 항상 그 자리 표현을. 따라서 숫자 표현 이라고 생각하게 됩니다.

따라서 올바른 질문은 "한베이스에서 다른베이스로 변환하는 방법"이 아니라 "어떤 숫자가 주어진 자릿수 문자열로 표시되는지 어떻게 알 수 있습니까?"와 " 주어진 번호 ".

자 이제 파이썬에서 숫자 표현을 숫자로 변환하는 함수와 반대의 작업을위한 함수를 만들어 봅시다. 참고 : 우리가 기능을 실행할 때 파이썬 코스의 것입니다 화면에 인쇄 가베이스 (10)에있어하지만 수가이가 않습니다 하지 컴퓨터 (그렇지 않은)베이스 (10)에 숫자를 유지하고 있음을 의미한다. 컴퓨터가 숫자를 나타내는 방식과 는 관련없습니다 .

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

우리가 이것을 테스트하자 :

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

변환 기능으로 무장 한 문제는 쉽게 해결됩니다.

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

시험:

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

참고 : 우리는 기본 10 표현을 통과 하지 못했습니다 ! 기본 표현을 숫자 로 변환 한 다음 숫자를 기본 . 그 숫자는 표현 되지 않았다 . (실제로 컴퓨터는 컴퓨터를 어떻게 든 표현해야했으며 칩에서 발생하는 전기 신호와 펑키 한 물건을 사용하여 컴퓨터를 표현했지만 분명히 0과 1은 아니 었습니다.)cbc


4
이것은 나에게 100 % 확신하지 않습니다. 사실, 당신은 컴퓨터가 플라톤의 수학자가되지 않기 때문에 (당신이 그것이 무엇인지 모르는 주장 할 수 있지만)과 알고리즘이 자료의 숫자의 임의의 순서 변환 할 수있는 몇 가지 표현으로 숫자로 변환 한 기본에 ; 콘크리트 기계로 표현할 수있는 시퀀스 만 변환 할 수 있습니다. 파이썬은 매우 유연합니다. C는 그렇게 용서하지 않았을 것입니다. 임의의 문자열을 에서 로 변환하는 방법을 묻는 것은 완벽하게 유효합니다 . 그러나 이것은 특정 염기 조합 (예 : 2 <-> 16)을 제외하고는 선형 시간에서만 가능합니다., B 2 , B 1 , B 2b1b2b1b2
rici

1
질문을하는 것은 타당하지만, 정답을 찾으려면 숫자가 추상 엔티티라는 사실을 아는 것이 가장 좋습니다.
Andrej Bauer

2
수행 은 AS,베이스 10 표현을 통해 수를 통과 fromDigits베이스 (10)에 반환 수를
apnorton

8
@ anorton : 아니요, 가장 확실하지 않습니다 . 파이썬은 기본 10 자리 숫자로 화면에 숫자를 인쇄하지만 숫자 자체는 그렇게 저장되지 않습니다. 내가 비난하려고 하는 것은 숫자가 파이썬 내에서 구현되는 방식과 관련 이 없다는 것입니다 . 그것은 중요하지 않습니다. 중요한 것은 그것들이 숫자처럼 행동한다는 것입니다.
Andrej Bauer

3
마지막으로 특정 유스 케이스, 36 미만의베이스 또는 충분한 고유 한 기호를 얻을 수있는 인스턴스로 제한되지 않는 모든베이스에 대한 일반적인 솔루션입니다.
J.Money

21

나는 이것을 이해하는 가장 좋은 방법은 외계인 (적어도 비유로서)과 토론하는 것이라고 생각합니다.

정의 는 기본 의 숫자 입니다. 는 숫자 의 문자열 임을 의미합니다 .xbx<b

예제 숫자 10010011011은 밑이 2 인 숫자이고, 문자열 68416841531은 밑이 10 인 숫자이며, BADCAFE는 밑이 16 인 숫자입니다.

이제 나는 모든 사람이 평생 동안 에서 일하도록 가르치는 행성 QUUX에서 자랐고 를 기반으로하는 당신을 만난다고 가정 해보십시오 . 숫자를 보여 주면 어떻게해야합니까? 그것을 해석하는 방법이 필요합니다.qb

정의 나는 다음 공식에 의해 기수 수를 해석 할 수있다 (참고 : 는 기수 의 수이다 )bbq

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

여기서 은 빈 문자열을 나타내고 는 숫자 끝나는 문자열을 나타냅니다 . 이 표기법에 대한 추가 사항이 추가되었다는 내 증거를 참조하십시오 .ϵs¯dd

여기서 무슨 일이 있었습니까? 베이스 숫자를 주었고 숫자가 실제로 무엇인지에 대한 이상한 철학없이 베이스 로 해석했습니다 .bq

키 이것 의 핵심은 와 가 기본 숫자 에서 작동하는 함수라는 것 입니다. 기본 숫자 (문자열)에 재귀 적으로 정의 된 간단한 알고리즘 입니다.×+qq


전체적으로 실제 숫자가 아닌 변수를 사용했기 때문에 약간 추상적 인 것처럼 보일 수 있습니다. 따라서 기본 13 생물 (기호 )이고 기호를 사용하여 7을 데 익숙 가정 해 봅시다 .0123456789XYZαβγδρζξ

그래서 나는 당신의 알파벳을 보았습니다.

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

그래서 나는 당신이 base 에서 일한다는 것을 알고 있으며 , 당신이 쓴 어떤 숫자가 어떤 base 7 숫자에 해당하는지 알고 있습니다.βξ

물리학에 대해 이야기하고 기본 상수 (예 : )에 대해 이야기하고 있다면 이것을 해석해야합니다.60Z8

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

그래서 나는 를 곱하는 것으로 시작 하지만 이것은 나에게 초등학교 물건입니다.βζ×βξ

Quux 곱셈표

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

그래서 찾아 내가 할을 :βζ×βξ

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

그래서 나는 이것을 멀리 가지고있다.

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

이제 이전에 언급 한 알고리즘을 사용하여 추가를 수행해야합니다.

δβγββδγδ

그래서

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

이 방법을 계속하면

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

요약 : 기본 자릿수 문자열 측면에서 숫자에 대한 자체 개념이 있는 경우 기본 산술 기본 연산-기본 에서 작동하는 기본 산술 연산을 기반으로 기본 에서 자체 시스템으로 숫자를 해석하는 방법이 있습니다 .b qqbq


1
글쎄, 그것은 구불 구불 한 선이 많았습니다. 그래도 컴퓨터가 어떻게해야합니까?
Griffin

1
@Griffin, 나는 당신이 (이상한) 질문을 조기에 요구하고 있다고 생각합니다. 프로그래밍 언어를 선택하고 기본 q 숫자 (숫자 목록으로 표시)를 더하고 곱하기위한 알고리즘을 입력 한 다음 기본 b 숫자를 기본 q 숫자로 해석하고 기본 b 숫자를 기본 q 숫자로 해석하는 함수를 정의하십시오. 나는이 모든 것을 설명했다.

나는 당신이 묘사하려는 개념을 알고 있습니다. 내 문제는 내 컴퓨터가 구불 구불 한 선을 사용할 수 없다는 것입니다.
Griffin

나는 당신이 무엇을 설명했는지 알고 있지만 실제로 적용하는 것은 훨씬 어렵습니다. 이 숫자를 정의하는 것은 쉽지 않습니다.
Griffin

1
또한 알파 자리를 가장 중요한 위치에 놓은 이유는 무엇입니까? 6 = & xi;이므로 7 = & α ;?
Giovanni Botta

9

이것은 Andrej 코드 리팩토링 (Python 3) 일뿐 입니다. Andrej의 코드 번호는 숫자 목록 (스칼라)을 통해 표시되는 반면 다음 코드 번호는 사용자 정의 문자열 에서 가져온 기호 목록을 통해 표시됩니다 .

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)

사용자 정의 기준에서 값을 표현으로 변환하려면 다음을 수행하십시오.

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

표현 (사용자 정의 기준)에서 값으로 변환을 수행하려면 다음을 수행하십시오.

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

한 custome base에서 다른 custome base로 기본 변환을 수행하려면 다음을 수행하십시오.

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

1
사이트에 오신 것을 환영합니다. 그러나 잘 최적화 된 소스 코드를 생성하는 것이이 사이트의 실제 내용이 아닙니다. Andrej의 코드는 개념을 명확하게 해주 며, 이것이 그의 대답에 필요한 것이지만, 그 이상으로 코드를 개선하는 것은 컴퓨터 과학 보다는 프로그래밍의 문제입니다 .
David Richerby

1
@DavidRicherby 나는 부분적으로 동의하지만,이 공헌은 너무 길어서 코멘트하기에는 너무 길었고 Andrej의 답변 근처에있을 수있는 가장 좋은 장소는 여기에 게시 한 이유입니다. 어쨌든 코드가 링크되어있는 주석으로 변환 할 수 있다고 생각하면 더 순수한 것이 아닐까요?
mmj

1

기본 변환의 기본 toDigits()조작은 @AndrejBauer answer 의 조작입니다. 그러나 그것을 만들기 위해 숫자의 내부 표현에서 숫자를 만들 필요가 없습니다.이 숫자는 기본적으로 밑 2 표현으로 변환됩니다. 원래 기본 표현으로 필요한 조작을 수행 할 수 있습니다.

첫 번째 단계는 반복적 인 모듈로 분할 연산을 수행하는 것입니다

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

내부 표현이 숫자이므로 0을 테스트하기 위해 specilaised 함수를 만들어야합니다

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

결국 우리는 학교에서 배운대로 목적지별로 표준 구분 인 modulo_div 연산을 만들어야합니다.

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

코드가 올바른지 확인하는 테스트 검사 만하면됩니다.

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]

게시 해 주셔서 감사하지만 우리는 코딩 사이트가 아니므로 큰 코드 블록은 여기에 대한 답변으로 적합하지 않습니다. 특히 질문에 명시 적으로 "코드가 필요하지 않습니다. 코드 뒤에 기본 수학 만 있으면됩니다."
David Richerby

@DavidRicherby 텍스트를 추가하려고했습니다.
Xavier Combelle

감사. 그리고 내가 말한 것에도 불구 하고이 페이지에 많은 코드가 있다는 것을 알았습니다!
David Richerby

0

컴퓨터 프로그램이 필요없는 기본 변환을 수행하는 쉬운 방법을 알고 있습니다. 그것은 어떤베이스에서베이스 2로 또는 그 반대로 변환하는 방법을 정의한 다음 먼저 첫 번째베이스에서베이스 2로 변환 한 다음베이스 2에서 다른베이스로 변환하여 한베이스에서 다른베이스로 커버하는 것입니다. 2는 어떤 염기에서나 곱하거나 나누기가 매우 쉽습니다.

어떤 기수를 기수 2로 변환하려면, 당신이해야 할 일은 어떤 숫자에 대해서도, 당신이 기수 2 표기법을 취하고 0에서 시작한 다음 각 숫자에 대해 그 자리가 0이고 해당 숫자가 1 인 경우 1을 더하는 것보다 두 배로 증가하면 해당 숫자 자체에 도달합니다. 이제 어떤 밑수에 해당 숫자가 주어지면 해당 밑수에 2를 나누어 몫과 나머지를 얻을 수 있습니다. 나머지가 1이면 마지막 이진수는 1이고 나머지가 0이면 마지막 이진수는 0입니다. 다시 2로 나눕니다. 나머지가 1이면 두 번째 마지막 숫자는 1이고 나머지가 0이면 두 번째 마지막 숫자는 0이며 몫이 0이 될 때까지 계속됩니다.

기본 2에서 기본으로 변환하려면 해당 기본에서 0부터 시작한 다음 왼쪽에서 오른쪽으로 이동하는 각 이진 숫자에 대해 그 숫자가 0이면 두 배 숫자를 두 번 누른 다음 1을 두 번 추가하십시오. 해당 숫자가 1 인 경우 밑


2 is so easy to multiply or divide by in any base.홀수 기지가 2의 거듭 제곱 중 하나 이상 (11과 13으로 시작)에 대해서는 알 수 없습니다.
greybeard

0

일부 중간베이스로 변환하지 않고베이스 n에서베이스 10으로 변환 할 수 있습니다.

예를 들어,베이스 n에서베이스 9로 변환하려면베이스 10으로 변환하는 알고리즘을 사용하여 "10"을 "9"로 바꿉니다. 다른 기지에서도 마찬가지입니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.