【问题标题】:How to realize Hexadecimal long division in Python3?Python3如何实现十六进制长除法?
【发布时间】:2019-07-17 09:18:04
【问题描述】:

我想实现计算器,计算器应该使用 2,8,10,16 符号。 我已经做了:addsubmul,但我不完全明白如何实现 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')

【问题讨论】:

标签: python-3.x algorithm hex calculator


【解决方案1】:

对于任何基地优先:

  1. 按位实现&lt;&lt; 左移和&gt;&gt; 右移

    在字符串上很简单,只需将数组向左或向右复制一个字符,然后从另一侧插入零。如果右移有符号基数的补码,则复制最重要的数字,因此正数为零,负数为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;
 }

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

对于小数,您需要添加小数点并在达到与以前相同的余数时结束除法,或者达到最大小数位数。您还需要稍微更改 B 的初始移位,因为它可以从一开始就比 A 大很多,所以你将是另一个,同时添加它向右移位。

所有这些都可以在字符串上实现,因此您不需要像现在那样转换为整数并返回,这很容易受到整数限制,因此限制了使用的数字的大小......

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

【讨论】:

    【解决方案2】:

    我没有完全理解您想要的操作是什么。但只要你想在 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 
    

    【讨论】:

      猜你喜欢
      • 2017-01-18
      • 1970-01-01
      • 2013-08-09
      • 2013-06-26
      • 1970-01-01
      • 2015-07-04
      • 1970-01-01
      • 1970-01-01
      • 2015-01-17
      相关资源
      最近更新 更多