คณิตศาสตร์ที่อยู่เบื้องหลังการแปลงจากฐานใด ๆ เป็นฐานใด ๆ โดยไม่ต้องผ่านฐาน 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
กริฟฟิควรจะบอกสิ่งที่นักเรียนหลายคนต้องการที่จะได้ยิน: ตัวเลขที่มีอยู่โดยไม่ถูกแสดงในฐาน จากนั้นคำตอบนั้นชัดเจน: เราต้องใช้อัลกอริธึมหนึ่งสำหรับการแปลงการแทนจำนวนในฐานที่กำหนดเป็นตัวเลข (นั่นคือสิ่งที่รับstringและส่งกลับint) และอัลกอริทึมที่ใช้ตัวเลขและส่งกลับค่าการเป็นตัวแทน ในฐานที่กำหนด
Andrej Bauer

1
@AndrejBauer คำถามเกี่ยวกับ CS: แม้ว่าจะไม่ได้พูดแบบนั้นนี่เป็นคำถามเกี่ยวกับอัลกอริทึมในการแปลงระหว่างการแทนตัวเลข [หมายเหตุที่ไม่เกี่ยวข้อง: ฉันลบความคิดเห็นที่ทำให้สับสน Griffin: โปรดแก้ไขคำถามของคุณเพื่ออัปเดต คนอื่น ๆ : โปรดนำไปแชท ]
กิลส์ 'หยุดความชั่วร้าย'

1
@Griffin มานานแล้วตั้งแต่คำถามเดิมของคุณ ฉันหวังว่าคุณจะพบคำตอบของคุณ ถ้าเป็นเช่นนั้นอาจเป็นความคิดที่ดีในการอัปเดตและยอมรับคำตอบหรือโพสต์ของคุณ ในระหว่างนี้ฉันได้พบความคิดที่ดีมาก (พูดคุยเกี่ยวกับการนำไปใช้ใน C ++) ในคลังเก็บรหัสของ Google วิธีแก้ปัญหาบางอย่างสำหรับปัญหานี้คือcode.google.com/codejam/contest/32003/dashboard ที่
IsaacCisneros

คำตอบ:


45

นี่เป็นคำถามพื้นฐานสำหรับฉันดังนั้นฉันเลยถ้าฉันบรรยายคุณสักหน่อย จุดสำคัญที่สุดสำหรับคุณที่จะเรียนรู้ที่นี่เป็นที่จำนวนไม่ได้เป็นตัวแทนหลักของมัน ตัวเลขเป็นวัตถุทางคณิตศาสตร์ที่เป็นนามธรรมในขณะที่การแสดงตัวเลขเป็นสิ่งที่เป็นรูปธรรมกล่าวคือลำดับของสัญลักษณ์บนกระดาษ (หรือลำดับของบิตในหน่วยความจำคำนวณหรือลำดับของเสียงที่คุณทำเมื่อคุณสื่อสารตัวเลข) สิ่งที่ทำให้คุณสับสนคือข้อเท็จจริงที่ว่าคุณไม่เคยเห็นตัวเลข แต่เป็นตัวเลขหลักเสมอ ดังนั้นคุณคิดว่าตัวเลขนั้นเป็นตัวแทน

ดังนั้นคำถามที่ถูกต้องในการถามไม่ใช่ "ฉันจะแปลงจากฐานหนึ่งไปยังอีกฐานข้อมูลได้อย่างไร" แต่ "ฉันจะทราบได้อย่างไรว่าตัวเลขใดที่จะแสดงด้วยสตริงตัวเลขที่กำหนด" และ "ฉันจะค้นหาตัวเลขหลักของ จำนวนที่กำหนด "

ดังนั้นให้เราสร้างฟังก์ชั่นสองอย่างใน Python หนึ่งอันสำหรับแปลงค่าตัวเลขเป็นตัวเลขและอีกอันทำหน้าที่ตรงกันข้าม หมายเหตุ: เมื่อเรารันฟังก์ชั่น Python จะพิมพ์บนหน้าจอจำนวนที่ได้รับในฐาน 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]

bc


4
b1b2b1b2

1
มันถูกต้องที่จะถามคำถาม แต่เพื่อค้นหาคำตอบที่ถูกต้องดีที่สุดที่จะตระหนักถึงความจริงที่ว่าตัวเลขเป็นหน่วยงานที่เป็นนามธรรม
Andrej Bauer

2
นี้ไม่ผ่านจำนวนผ่านฐานตัวแทน 10 ขณะที่fromDigitsผลตอบแทนจำนวน 10 ฐาน
apnorton

8
@anorton: ไม่มีแน่นอนที่สุดมันไม่ได้ Python พิมพ์หมายเลขบนหน้าจอด้วยการแสดงตัวเลข 10 หลัก แต่ตัวตัวเลขนั้นไม่ได้ถูกจัดเก็บในแบบนั้น สิ่งที่ฉันพยายามจะเอาชนะก็คือมันไม่เกี่ยวข้องกับวิธีการใช้ตัวเลขในงูหลาม ไม่เป็นไร. สิ่งเดียวที่สำคัญคือพวกมันประพฤติตัวเหมือนตัวเลข
Andrej Bauer

3
ในที่สุดการแก้ปัญหาทั่วไปสำหรับฐานใด ๆ และไม่ จำกัด เฉพาะกรณีการใช้งานฐานน้อยกว่า 36 หรือกรณีที่คุณสามารถเกิดขึ้นกับสัญลักษณ์ที่ไม่ซ้ำกันมากพอ
J.Money

21

ฉันคิดว่าวิธีที่ดีที่สุดที่จะเข้าใจสิ่งนี้คือการพูดคุยกับมนุษย์ต่างดาว (อย่างน้อยก็เป็นการเปรียบเทียบ)

xbx<b

ตัวอย่างสตริงของตัวเลข 10010011011 เป็นตัวเลขในฐาน 2 สตริง 68416841531 เป็นตัวเลขในฐาน 10 BADCAFE เป็นตัวเลขในฐาน 16

qb

bbq

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

ϵs¯dd

bq

×+qq


0123456789XYZαβγδρζξ

ดังนั้นฉันจึงเห็นตัวอักษรของคุณและทำเป็นตารางดังนี้:

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

βξ

60Z8

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

βζ×βξ

ตารางสูตรคูณ Quux

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

βζ×βξ

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

ดังนั้นฉันจึงได้มาไกลขนาดนี้

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

ตอนนี้ฉันต้องทำการเพิ่มโดยใช้อัลกอริทึมที่กล่าวถึงก่อนหน้านี้:

δβγββδγδ

ดังนั้น

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

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

qbq


1
นั่นก็คือเส้นสายที่บิดเบี้ยว ฉันจะทำให้คอมพิวเตอร์ทำเช่นนั้นได้อย่างไร
กริฟ

1
@Griffin ฉันคิดว่าคุณกำลังถามคำถาม (แปลก) ก่อนกำหนด คุณเลือกภาษาการเขียนโปรแกรมและพิมพ์อัลกอริธึมสำหรับการบวกและการคูณกับหมายเลข q ฐาน (แสดงเป็นรายการของตัวเลข) จากนั้นกำหนดฟังก์ชันเพื่อแปลตัวเลขฐาน b เป็นตัวเลขฐาน q และตีความหมายเลขฐาน b เป็นตัวเลขฐาน q ฉันอธิบายทั้งหมดนี้แล้ว

สิ่งที่ฉันรู้แนวคิดของคุณพยายามที่จะวาดภาพ ปัญหาของฉันคือคอมพิวเตอร์ของฉันไม่สามารถใช้เส้นสายของคุณได้
กริฟ

ฉันรู้ว่าสิ่งที่คุณอธิบาย แต่การนำไปใช้จริงนั้นยากกว่ามาก คุณเห็นว่าการกำหนดตัวเลขเหล่านั้นไม่ใช่เรื่องง่าย
กริฟ

1
ทำไมคุณถึงดรอปอัลฟ่าดิจิตในตำแหน่งที่สำคัญที่สุด? ตั้งแต่ 6 = & xi ;, จะไม่ 7 = & alpha; & alpha ;?
Giovanni Botta

9

นี่เป็นเพียงการสร้างใหม่ (Python 3) ของรหัสของ Andrej ในหมายเลขรหัสของ 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

หากต้องการทำการแปลงฐานจากฐานหนึ่งไปยังอีกฐานหนึ่ง:

>>> 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 อย่างไรก็ตามเพื่อให้มันไม่จำเป็นต้องสร้างตัวเลขในการเป็นตัวแทนภายในของตัวเลขซึ่งเป็นพื้นการแปลงจากและเป็นฐาน 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

เนื่องจากการแทนค่าภายในเป็นตัวเลขจึงต้องสร้างฟังก์ชันเฉพาะสำหรับทดสอบศูนย์

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 จากนั้นสำหรับแต่ละหลักตามลำดับจากซ้ายไปขวาสองหลักหากตัวเลขนั้นเป็นศูนย์และ สองครั้งที่เพิ่มมากกว่า 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.ฉันไม่เห็นว่าสำหรับฐานแปลก ๆ ที่มากกว่าหนึ่งจากพลังใด ๆ ของสอง (11 และ 13 เพื่อเริ่มต้นด้วย)
greybeard

0

คุณสามารถแปลงจากฐาน n เป็นฐาน 10 โดยไม่ต้องแปลงเป็นฐานระดับกลาง

หากต้องการแปลงจากฐาน n เป็นฐาน 9 คุณใช้อัลกอริทึมสำหรับการแปลงเป็นฐาน 10 และแทนที่“ 10” ด้วย“ 9” เหมือนกันสำหรับฐานอื่น ๆ

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.