如何在Python3中实现十六进制长除法?

时间:2019-07-17 09:18:04

标签: python-3.x algorithm hex calculator

我想实现计算器,calc应该使用2,8,10,16表示法。 我已经做了:添加 sub mul ,但是我不完全了解如何实现 div 16种符号。是的,我是Python的新手。
如何为我的班级计算器实现十六进制长除法?

我的代码:

numbers = {'0': '0', '1': '1', '2': '2', '3': '3', '4': '4', '5': '5', '6': '6', '7': '7', '8': '8', '9': '9',
       'A': '10', 'B': '11', 'C': '12', 'D': '13', 'E': '14', 'F': '15', '-': '-'}

rev_numbers = {'0': '0', '1': '1', '2': '2', '3': '3', '4': '4', '5': '5', '6': '6', '7': '7', '8': '8', '9': '9',
           '10': 'A', '11': 'B', '12': 'C', '13': 'D', '14': 'E', '15': 'F', '-': '-'}


class Calculator:


def __init__(self, num, num2, system):
    self.result = []
    self.shift = 0  
    self.system = system  

def __add__(self, l1, l2):
    self.result = []
    max_len = max(len(l1), len(l2))
    l1, l2 = l1.rjust(max_len, '0'), l2.rjust(max_len, '0')
    if self.system == 16:
        l1 = [numbers[value] for value in l1 if
              value in numbers.keys()]  
        l2 = [numbers[value] for value in l2 if value in numbers.keys()]
    for i in range(max_len - 1, -1, -1):
        r = int(l1[i]) + int(l2[i]) + self.shift
        self.shift = r // self.system
        r = r % self.system
        self.result.append(str(r))

    if self.shift > 0:
        self.result.append(str(self.shift))

    r = [rev_numbers[value] for value in self.result if
         value in rev_numbers.keys()]  

    self.shift = 0

    return ''.join(r)[::-1]

def __sub__(self, l1, l2):
    char = ''
    if len(l1) < len(l2):
        l1, l2 = l2, l1
        char = '-'
    max_len = max(len(l1), len(l2))
    l1, l2 = l1.rjust(max_len, '0'), l2.rjust(max_len, '0')
    if self.system == 16:
        l1 = [numbers[value] for value in l1 if value in numbers.keys()]
        l2 = [numbers[value] for value in l2 if value in numbers.keys()]
    for i in range(max_len - 1, -1, -1):
        r = int(l1[i]) - int(l2[i]) - self.shift
        if r >= 0:
            self.result.append(str(r))
            self.shift = 0
        else:
            r += self.system
            self.shift = 1
            self.result.append(str(r))

    if char == '-':
        self.result.append(char)

    r = [rev_numbers[value] for value in self.result if value in rev_numbers.keys()]

    self.result = []

    r = ''.join(r)[::-1]

    return r.lstrip('0')

2 个答案:

答案 0 :(得分:0)

我不完全了解您想要执行的操作。但是,只要您要在python中除长数,就可以在下面看到我的答案。

# Python3 program to implement division  
# with large number  
import math 

# A function to perform division of  
# large numbers  
def longDivision(number, divisor):  

    # As result can be very large  
    # store it in string  
    ans = "";  

    # Find prefix of number that  
    # is larger than divisor.  
    idx = 0;  
    temp = ord(number[idx]) - ord('0'); 
    while (temp < divisor): 
        temp = (temp * 10 + ord(number[idx + 1]) -
                            ord('0')); 
        idx += 1; 

    idx +=1; 

    # Repeatedly divide divisor with temp.  
    # After every division, update temp to  
    # include one more digit.  
    while ((len(number)) > idx):  

        # Store result in answer i.e. temp / divisor  
        ans += chr(math.floor(temp // divisor) + ord('0'));  

        # Take next digit of number 
        temp = ((temp % divisor) * 10 + ord(number[idx]) -
                                        ord('0')); 
        idx += 1; 

    ans += chr(math.floor(temp // divisor) + ord('0')); 

    # If divisor is greater than number  
    if (len(ans) == 0):  
        return "0";  

    # else return ans  
    return ans;  

# Driver Code 
number = "1248163264128256512";  
divisor = 125;  
print(longDivision(number, divisor));  

# This code is contributed by mits 

答案 1 :(得分:0)

对于任何基础优先:

  1. 按数字左移<<和右移>>算术

    在字符串上使用

    很容易,只需将数组向左或向右复制一个字符,然后从另一侧插入零即可。如果右移的带符号基的补码是数字,则您复制最高有效数字,因此正数为零,负数为base-1。这样号码仍然会被签名...

    此运算也是基数的乘法/除法。

    A*Base = A<<1
    A/Base = A>>1
    
    A*Base*Base = A<<2
    A*Base*Base*Base = A<<3
    ...
    
  2. 两个数字的减法

    您声称您已经拥有这个...

  3. 两个数字的实现比较

    这与减法相同,只是在减法溢出或归零时不返回结果,而是返回……这将告诉您数字是==,<还是>。我通常将结果编码为

    -1 A<B
     0 A==B
    +1 A>B 
    

现在很久了

C = A/B // division
D = A%B // remainder

我不是用python编写代码,而是用伪代码表示无符号整数,就像这样:

C=0;  // division
D=A;  // remainder
q=1;  // actual weight of B

if (B==0) handle division by zero !!!

while (A>=B) // shift B so its biggest and still smaller or equal to A
 {
 B=B<<1;  
 q=q<<1;
 }
if (q>1)
 {
 B=B>>1;
 q=q>>1;
 }

for (;q>0;) // long division
 {
 while (D>=B)
  {
  D=D-B;
  C=C+q;
  }
 B=B>>1;    // shift right by one digit
 q=q>>1;
 }

对于带符号的数字,您可以先提取结果的符号,然后除以abs值。

对于小数,您需要添加小数点并在达到与以前相同的余数时结束除法,否则将达到最大小数位数。您还需要稍微改变B的初始位移,因为它从一开始就可能比A大,因此添加正确的位移时您将是另一个。

所有这些操作都可以在字符串上进行,因此您不需要像现在那样转换为int和back,因为它容易受到整数限制的限制,因此会限制所用数字的大小...

如您所见,长除法与移位和加法非常相似(只需向相反方向移位并减去而不是加法即可)