ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

更强更方便的进制转换工具

2021-02-01 18:02:41  阅读:282  来源: 互联网

标签:10 转换 target Decimal return num 更强 basechange 进制


最近,我仿照https://blog.csdn.net/Eyizoha/article/details/94897931?locationNum=9&fps=1上的2-36进制转换的代码做出了一个更强的2-62进制转换工具,不仅可以进行普通的进制转换,还可以直接进行不同进制计算,代码如下(Python3):

from decimal import *
getcontext().prec = 1000
def trans(num):	# 输入数字换为字母或输入字母转换为数字
    if type(num) == int:
        if num < 10:
            return str(num)
        elif num < 36:
            return chr(ord('a') + num - 10)
        else:
            return chr(ord('A') + num - 36)
    else:
        if num.isdigit():
            return int(num)
        elif num.islower():
            return ord(num) - ord('a') + 10
        elif num.isupper():
            return ord(num) - ord('A') + 36

def check(num, base, target): # 待转换数字,当前进制,目标进制
    if type(base) is not int or base < 2 or base > 62 or type(target) is not int or target < 2 or target > 62:
        print('非法进制数!')
        return False
    if type(num) is int or type(num) is Decimal:
        num = str(num)
    elif type(num) is str and len(num) != 0:
        num = num
    else:
        print('非数字输入!')
        return False

    if num.count('.') > 1:
        print('多个小数点!')
        return False

    if not num.replace('.', '').isalnum():
        print('含有其他字符!')
        return False

    for c in num.replace('.', ''):
        if trans(c) >= base:
            print('字符超过进制允许!')
            return False

    while len(num) > 1:
        if num[0] == '0' and num[1] != '.':
            num = num[1:]
        else:
            break
    return num

def basechange(num, base, target, precision=8): # 待转换数字,当前进制,目标进制,精度
    num = check(num, base, target)
    if num is False:
        return None
    point = num.find('.')
    if point == -1:
        point = len(num)
    radix = num.replace('.', '')
    if target == 10:
        int_part = radix[:point][::-1]
        frac_part = radix[point:]
        s = 0
        ss = 0
        for i in range(len(int_part)):
            s += trans(int_part[i]) * base ** i
        for i in range(len(frac_part)):
            ss += trans(frac_part[i]) / base ** (i+1)
        return str(s) + str(ss)[1:]
    elif base == 10:
        int_part = int(radix[:point])
        frac_part = Decimal('0.'+radix[point:])
        s = ''
        while True:
            s += trans(int_part % target)
            int_part //= target
            if int_part == 0:
                break
        s = s[::-1]
        if frac_part != 0:
            s += '.'
            ct = 0
            while frac_part != 0 and ct < precision:
                frac_part *= target
                s += trans(int(frac_part))
                frac_part -= int(frac_part)
                ct += 1
        return s
    else:
        return basechange(basechange(num, base, 10, precision=precision), 10, target, precision=precision)

def abpl(num1,base1,num2,base2,target):
    a,b=basechange(num1, base1, 10, 1000),basechange(num2, base2, 10, 1000)
    return basechange(Decimal(a)+Decimal(b),10,target,1000) #加法

def absu(num1,base1,num2,base2,target):
    a,b=basechange(num1, base1, 10, 1000),basechange(num2, base2, 10, 1000)
    return basechange(Decimal(a)-Decimal(b),10,target,100) #减法

def abmu(num1,base1,num2,base2,target):
    a,b=basechange(num1, base1, 10, 1000),basechange(num2, base2, 10, 1000)
    return basechange(Decimal(a)*Decimal(b),10,target,100) #乘法

def abdi(num1,base1,num2,base2,target):
    a,b=basechange(num1, base1, 10, 1000),basechange(num2, base2, 10, 1000)
    return basechange(Decimal(a)/Decimal(b),10,target,100) #除法

def abpo(num1,base1,num2,base2,target):
    a,b=basechange(num1, base1, 10, 1000),basechange(num2, base2, 10, 1000)
    return basechange(Decimal(a)**Decimal(b),10,target,100) #乘方

def abrt(num1,base1,num2,base2,target):
    a,b=basechange(num1, base1, 10, 1000),basechange(num2, base2, 10, 1000)
    return basechange(Decimal(a)**Decimal(1/Decimal(b)),10,target,100) #开方

def abfl(num1,base1,num2,base2,target):
    a,b=basechange(num1, base1, 10, 1000),basechange(num2, base2, 10, 1000)
    return basechange(Decimal(a)//Decimal(b),10,target,100) #除法

以下是演示:

abpo(2,10,100,10,62)
'qADiGrP0AKRA2S8Uw'
abmu('acc',62,'python',62,10)
'917683977345620'
abrt(2,10,100,10,62)
'1.0qJHxLPX0S8850kC42G0iHHAWSopXPjVS0okYnGj5tINlPl6xyZ7j4nBqCcrjw7q5Stze0ppJMJ5rGcETWKEqsZMjj80gBUIqTke'

但存在一些缺陷,例如:

abpo('gig',62,100,62,62)
含有其他字符!
abpo(31,10,800,10,62)
含有其他字符!

这是因为当数字较大的时候,可能会使用科学计数法(有一个+号)。
希望日后可以改进。

标签:10,转换,target,Decimal,return,num,更强,basechange,进制
来源: https://blog.csdn.net/qq_34606903/article/details/113525647

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有