进制转换原理和python实现

本文详细阐述了如何使用Python将非十进制数转换为十进制,包括直接调用函数和手动实现的方法,以及如何进行10进制与其他进制的转换,通过实例演示了转换过程。


前言

生活中一般大家使用的数字通常是用十进制(decimal system)表示,意味着

  1. 每一位数上满十,更高一位上数字加一,如9加1等于10
  2. 按权展开,第一位权为100, 第二位101 ……以此类推,第N位10(N-1),该数的数值等于每位的数值*该位对应的权值之和。
    n u m b e r ( a N a N − 1 . . . a 1 ) ( 10 ) = ∑ i = 1 N a i ∗ 1 0 i − 1 = a N ∗ 1 0 N − 1 + a N − 1 ∗ 1 0 N − 2 + . . . + a 1 number(a_{N}a_{N-1}...a_{1})(10) = \sum_{i=1}^{N}a_{i}*10^{i-1} = a_{N} * 10^{N-1} +a_{N-1}*10^{N-2} + ...+ a_{1} number(aNaN1...a1)(10)=i=1Nai10i1=aN10N1+aN110N2+...+a1

而一些别的进制也存在于生活中,如时间秒和分之间是60进制(sexagesimal),计算机使用的是二进制(binary system),月和年是12进制(duodecimal number system),7天是1周,所以是7进制(septinary)。

如何将不同进制的数字进行转换呢? 这里分为三种情况:

  1. 将其余进制转位10进制
  2. 将10进制转为其余进制
  3. 其余进制之间互相转换

本文将介绍不同进制的转换的原理和如何使用python实现


一、将非10进制数转为10进制数

原理

这个是相对简单的,假设某X进制数,表示为number(X),则每个位数上可能有X个状态,从0到X-1。例如,

  • 2进制下,数字为0,1,超过1则更高的数位上加1。如1的下一个数字是10(2)
  • 12进制下,符号首先是普通的0到9,用A代表10,B代表11,超过11则更高的数位加1。如B(12)的下一个数字是10(12)

参考十进制的权重定义,在X进制下权为X,所以将数字转为10进制时
n u m b e r ( 10 ) = n u m b e r ( a N a N − 1 . . . a 1 ) ( X ) = ∑ i = 1 N a i ∗ X i − 1 number(10) = number(a_{N}a_{N-1}...a_{1})(X) = \sum_{i=1}^{N}a_{i}*X^{i-1} number(10)=number(aNaN1...a1)(X)=i=1NaiXi1
= a N ∗ X N − 1 + a N − 1 ∗ X N − 2 + . . . + a 1 = a_{N} * X^{N-1} +a_{N-1}*X^{N-2} + ...+ a_{1} =aNXN1+aN1XN2+...+a1

例如,将2AB(12)转为10进制,
n u m b e r ( 10 ) = 2 A B ( 12 ) = 2 ∗ 1 2 3 − 1 + A ∗ 1 2 2 − 1 + B ∗ 1 2 1 − 1 number(10) = 2AB(12)=2 * 12^{3-1} + A * 12 ^{2-1} +B*12^{1-1} number(10)=2AB(12)=21231+A1221+B1211
A ( 12 ) = 10 ( 10 ) , B ( 12 ) = 11 ( 10 ) A(12)=10(10),B(12) = 11(10) A12=10(10),B12=11(10)
n u m b e r ( 10 ) = 2 A B ( 12 ) = 2 ∗ 1 2 2 + 10 ∗ 12 + 11 ∗ 1 = 419 ( 1 ) number(10) = 2AB(12) = 2*12^{2} + 10*12+11*1=419(1) number(10)=2AB(12)=2122+1012+111=4191

python 实现

1. 不讲武德直接调用函数

int(x, base=10),int()函数的用法可以参考这个文章,此处简单介绍

参数
x – 字符串或数字。
base – 进制数,默认十进制。

  1. 当x是字符串时,则认为给定字符串对应的数字是base指定进制下的数字,然后再将其转换为十进制下的数字输出。若不输入base值时,base默认为10。字符串可能存在abc等英文字母代表相应进制下数字,不分大小写。a:10,b:11,以此类推。因此base最高为36,因为0到9共10个数,英文字母共26个。
int('10')         #output:10
int('10', 12)     #output:12,12进制下的10,是十进制下的12
int('1a', 12)     #output:22
  1. 当x是数字时,后面不可加base,将float型小数数字转为10进制下整数int型,此处与主题无关

2. 手动实现int()

假设当出现高于10进制时候,使用的字符是英语字母a到z,不分大小写。假设给定的是合理的字符。

def int_self(num_str: str, base = 10):
    # ord('0') = 48, ord('9') = 57, 
    # ord('a') = 97, ord('z') = 122, 
    # ord('A') = 65, ord('Z') = 90
    n = len(num_str)
    ans = 0
    for i in range(n-1, -1, -1):
        if 48 <= ord(num_str[i]) <= 57: 
            ans += int(num_str[i]) * base**(n - i - 1)
        elif 97 <= ord(num_str[i]) <= 122 or 65 <= ord(num_str[i]) <= 90:
            ans += (ord(num_str[i].lower()) - 97 + 10) * base**(n-i-1)
        else:
            return False    #当有其他字符时候,报错 
    return ans  

int_self('10', 12)    # output: 12

二、将10进制数转为非10进制数

原理:

在上一个节已经知道
n u m b e r ( 10 ) = n u m b e r ( a N a N − 1 . . . a 1 ) ( X ) = ∑ i = 1 N a i ∗ X i − 1 number(10) = number(a_{N}a_{N-1}...a_{1})(X) = \sum_{i=1}^{N}a_{i}*X^{i-1} number(10)=number(aNaN1...a1)(X)=i=1NaiXi1
= a N ∗ X N − 1 + a N − 1 ∗ X N − 2 + . . . + a 1 = a_{N} * X^{N-1} +a_{N-1}*X^{N-2} + ...+ a_{1} =aNXN1+aN1XN2+...+a1
成立。现在需要将十进制下的数number(10)转化为 X进制下的数字 ( a N a N − 1 . . . a 1 ) ( X ) (a_{N}a_{N-1}...a_{1})(X) (aNaN1...a1)(X)

先观察式子, n u m b e r ( 10 ) = a N ∗ X N − 1 + a N − 1 ∗ X N − 2 + . . . + a 2 ∗ X 1 + a 1 number(10) = a_{N} * X^{N-1} +a_{N-1}*X^{N-2} + ...+ a_{2} * X^{1}+a_{1} number(10)=aNXN1+aN1XN2+...+a2X1+a1,右边式子(RHS: right hand side)除以X,除了最后一项 a 1 a_{1} a1,其余项都含有X的次方,都可以整除X,而且 a 1 < X a_{1} < X a1<X,因此余数为 a 1 a_{1} a1,因此可以

  1. 用左边式子(LHS: left hand side)和右边式子(RHS)除以X的余数得 a 1 a_{1} a1
  2. 然后将左边式子减 a 1 a_{1} a1,然后除以X。此时
    L H S = n u m b e r ( 10 ) − a 1 X LHS = \frac{number(10)-a_{1} }{X} LHS=Xnumber(10)a1
    R H S = a N ∗ X N − 2 + a N − 1 ∗ X N − 3 + . . . + a 2 RHS = a_{N} * X^{N-2} +a_{N-1}*X^{N-3} + ...+ a_{2} RHS=aNXN2+aN1XN3+...+a2
  3. 跟求 a 1 a_{1} a1相同,重复1和2,可以依次从低位到高位,求得各数位上的数值 a i a_{i} ai

python 实现

因为十进制的数已知,因此使用整数int为格式进行输入,而X进制可能存在大于十的数,所以用字符串输出。但对于大于十进制的数,余数可能大于9,需要将其转换为对应英文字母。此处为简化,全转为小写。

def convertToBase(num: int, base: int) -> str:
    if num == 0:
        return "0"
    negative = num < 0
    num = abs(num)
    digits = []
    while num:
        temp = num%base
        if temp <10:
            digits.append(str(num % base))
        else:
            # ord('a') = 97, ord('z') = 122, 
            temp_str = chr(temp - 10 + 97)
            digits.append(temp_str)
        num //= base
    if negative:
        digits.append('-')
    return ''.join(reversed(digits))

convertToBase(22,12)  # output: '1a'

三、其余进制之间互相转换

目前没有想到什么好办法,但可以根据上述部分,将初始值转为十进制,再将其转为要求进制下。

# num_str_input 为已知的字符串,base_input为初始进制值,
# temp_10为十进制数字,base_output为要求转为的进制值
# output为结果字符串
temp_10 = int(num_str_input, base_input)
output = convertToBase(temp_10, base_output)
output

总结

以上就是如何对进制进行转换的原理及python实现,基于数字0到9和26个英文字符(不分大小写),分别实现36进制以内的非十进制和十进制的转换。

<think>首先,用户的问题是:“我想查找使用Python将十进制数转换为十二进制数的方法 请问Python实现进制转换为十二进制的方法”。这与之前的引用相关,因为他们讨论十进制转换到其他进制。 从引用中提取关键信息: - 引用[1]展示了Python代码转换十进制到任意进制(十六进制以内),使用了列表存储数字字母(0-9,A-F),并使用除法取余操作。 - 引用[2]详细描述了十进制转八进制的方法,使用了“除8取余法”,并提供了Python实现样例。 - 引用[3]提到Python内置函数如bin(), oct(), hex()用于转换到二进制、八进制、十六进制,但这些是针对特定进制的,不是通用的。 - 引用[4]讨论了十进制转二进制,但未提供新代码。 - 引用[5]特别提到了十进制十二进制的相互转换,并提供了Python代码示例。 用户明确想要十进制转十二进制的方法。引用[5]直接解决了这个问题,因为它标题是“python之 十进制与十二进制 相互转换”,并给出了代码。 引用[5]的代码: - 输入格式如"0w1A"代表十二进制数,"0w"是前缀。 - 代码解析十二进制字符串到十进制:使用循环枚举,处理字母字符(如'A'转换为10),然后计算值。 - 十进制转十二进制部分:使用循环除以12,取余,拼接字符串。使用字符串'0123456789AB'来映射余数到数字或字母(A=10,B=11)。 用户需求是十进制转十二进制,所以我应该专注于引用[5]中的转换部分。 在引用[5]代码中: - 输入处理:"0w"前缀被剥离。 - 十进制转十二进制: ```python r = '' while m > 0: r = '0123456789AB'[m % 12] + r # 映射余数到字符 m = (m - m % 12) // 12 # 等同于 m //= 12 print('0w' + (r or '0')) # 添加前缀,如果r为空则输出'0' ``` 这类似于引用[1][2]的方法:除基取余法。 用户提到“尽可能多的参考用户上一次的问题你的回答”。但在对话历史中,用户上一次问题是关于十进制转十二进制的方法。之前的系统指令是关于回答格式的,但没有之前的用户问题历史。所以,我假设这是新会话或用户首次提问此问题。 系统指令要求: - 使用$...$格式内联数学表达式。 - 独立公式用$$...$$。 - LaTeX语法正确。 - 使用中文回答。 - 生成相关问题。 - 在回答中引用的段落末尾添加引用标识如[^1]。 用户问题:“我想查找使用Python将十进制数转换为十二进制数的方法 请问Python实现进制转换为十二进制的方法” 我应该提供一个清晰的Python实现进制转十二进制的方法,参考引用[5]。 结构化回答: 1. 介绍十进制转十二进制原理:除基取余法。 2. 提供Python代码示例。 3. 解释代码逻辑。 4. 添加相关问题。 使用引用标识:当引用内容时添加[^n]。 引用[5]是最相关的,所以我会主要基于它。 代码优化:引用[5]中使用了(m - m % 12) // 12,这等价于m // 12,因为整数除法。可以简化。 在Python中,整数除法是//,所以直接m = m // 12。 映射字符串:'0123456789AB',因为十二进制需要数字0-9字母A,B代表10,11。 输入输出:引用[5]有前缀"0w",但用户可能不需要。我应该提供一个通用函数。 例如: ```python def decimal_to_duodecimal(decimal): if decimal == 0: return '0' digits = '0123456789AB' # 十二进制字符 result = '' num = decimal while num > 0: remainder = num % 12 result = digits[remainder] + result num = num // 12 return result ``` 测试:decimal = 10 → 'A', decimal = 11 → 'B', decimal = 12 → '10'(因为12÷12=1余0,所以'10'),decimal = 13 → '11',等等。 处理decimal=0的情况。 现在,构建回答: - 开头解释十进制转十二进制的步骤。 - 提供代码。 - 解释代码。 - 生成相关问题。 使用中文回答。 内联数学:如除基取余法,可以提到数学表达式如 $n = q \times 12 + r$。 相关问题:例如,“如何进行十二进制转十进制?”、“Python内置函数支持十二进制吗?”、“其他进制转换方法”。 </think>### Python实现进制转换为十二进制的方法 十进制数转换成十二进制数的原理是“除基取余法”,这是一种通用的进制转换算法。具体步骤如下: 1. **初始化**:设输入的十进制数为 $n$。 2. **循环除法**:重复以下过程,直到商为0: - 计算余数:$r = n \mod 12$。 - 将余数映射到十二进制的字符(0-9 对应数字,10 对应 'A',11 对应 'B')。 - 将映射后的字符添加到结果字符串的前面。 - 更新被除数:$n = \lfloor n / 12 \rfloor$(向下取整)。 3. **处理特殊情况**:如果输入为0,则直接返回 '0'。 4. **输出**:将所有余数字符从下到上拼接,得到十二进制结果。 这种方法的数学基础是整数除法模运算:十进制数 $n$ 可以表示为: $$n = q_k \times 12^k + \cdots + q_1 \times 12^1 + q_0 \times 12^0$$ 其中 $q_i$ 是余数序列[^2][^5]。 ### Python代码实现 基于上述原理,参考引用中的代码(特别是引用[5]的转换部分),我提供一个简洁的Python函数。该函数处理十进制数到十二进制的转换,并支持整数输入。 ```python def decimal_to_duodecimal(decimal_num): """ 将十进制数转换为十二进制字符串。 参数: decimal_num: int, 输入的十进制数(非负整数)。 返回: str, 十二进制结果字符串。 """ if decimal_num == 0: return '0' # 处理输入为0的情况 digits = '0123456789AB' # 十二进制字符映射:0-9对应数字,10->'A', 11->'B' result = '' # 初始化结果字符串 num = decimal_num while num > 0: remainder = num % 12 # 计算余数 result = digits[remainder] + result # 映射余数并添加到结果前面 num = num // 12 # 更新为商,继续除法 return result # 示例测试 if __name__ == "__main__": decimal = int(input("请输入一个十进制数: ")) duodecimal_result = decimal_to_duodecimal(decimal) print(f"十进制数 {decimal} 的十二进制表示为: {duodecimal_result}") ``` ### 代码解析 - **字符映射**:十二进制需要表示数字1011,因此使用字符串 `'0123456789AB'` 进行索引(余数 $r$ 作为索引)[^5]。 - **循环除法**:使用 `while` 循环持续除以12: - `num % 12` 获取余数。 - `digits[remainder]` 将余数转换为对应字符(例如,余数10映射到 'A')。 - 字符串拼接时,新字符添加在结果前面(`result = digits[remainder] + result`),确保顺序正确(从最高位到最低位)。 - `num // 12` 更新商值,直到商为0结束循环。 - **输入处理**:示例中允许用户输入十进制数,并输出十二进制结果。输入应为非负整数。 - **测试示例**: - 输入 `10` → 输出 `'A'`(因为 $10 \mod 12 = 10 \rightarrow \text{'A'}$)。 - 输入 `12` → 输出 `'10'`(因为 $12 \div 12 = 1 \cdots 0$, 所以拼接为 '10')。 - 输入 `22` → 输出 `'1A'`(因为 $22 \div 12 = 1 \cdots 10 \rightarrow \text{'1A'}$)。 ### 优缺点注意事项 - **优点**:算法简单高效,时间复杂度为 $O(\log_{12} n)$,适用于任意大小的整数。 - **缺点**:不直接支持负数浮点数;如需要,可扩展为处理负数(例如,添加负号前缀)。 - **与内置函数比较**:Python内置函数如 `bin()`、`oct()`、`hex()` 只支持二进制、八进制十六进制,不支持十二进制,因此自定义函数是必要的[^3]。 ### 相关问题 1. 如何实现十二进制转十进制?例如,将 '1A' 这样的字符串转换回十进制数。 2. Python中有哪些内置函数用于进制转换?它们支持哪些进制? 3. 如何扩展这个方法以支持负数或小数(浮点数)的进制转换? 4. 十二进制在实际应用中有哪些场景?例如,在某些编程挑战或历史系统中使用。 [^1]: 引用[1]提供了十进制转任意进制的一般方法,使用除基取余法字符列表映射。 [^2]: 引用[2]详细解释了除基取余法的步骤,适用于八进制转换原理相同。 [^3]: 引用[3]展示了Python内置进制转换函数,但仅限于二进制、八进制十六进制。 [^4]: 引用[4]讨论了进制转换中的字符表示,但不包含十二进制实现。 [^5]: 引用[5]直接提供了十进制十二进制相互转换的代码示例,是本文实现的主要参考。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值