首页 文章

在不同基础上对非常大的数字执行操作的最快方法

提问于
浏览
0

我收到一个非常大的基于2 ^ k的数字的数字列表(k <= 30,数字量<= 10 ^ 7) .

我需要做的是得到两个数字(让我们称之为X和Y),减去它们(A = X-Y,B = Y-X)并返回A和B的二进制表示 .

我当前的代码如下所示:

k = int(input())
base = pow(2, k)
numbersX = stdin.readline().split()
digitsX = len(numbersA) - 1

x = 0
i = 1
while i <= digitsX:
    factor = pow(base, digitsX - i)
    x += int(numbersX[i]) * factor
    i += 1

(类似于Y)

我只是简单地将接收到的数字转换为小数,然后减去并获得二进制表示 . 它工作但很慢 . 你会建议其他解决方案吗?

Sample input:
4 (for k)
6 15
2 7
So X = 6 15 = 6*16^1 + 15*16^0 = 96 + 15 = 111 (decimal)
Y = 2 7 = 2*16^1 + 7*16^0 = 32 + 7 = 39 (decimal)
A = X – Y = 111 – 39 = 72
B = Y – X = 39 – 111 = -72
Output:
01001000 (A in SM binary)
10111000 (B in U2 binary)

2 回答

  • 0

    这是一种将任何基数中的数字转换为整数的方法:

    def to_int(digits, base=1024):
        place = 1
        ret = 0
        for digit in reversed(digits):
            ret += place*digit
            place *= base
        return ret
    

    如果你的基数总是2的幂( 2^10 = 1024 ),你也可以这样做(可能效率更高):

    def to_int2(digits, log2base=10):
        ret = 0
        for digit in digits:
            ret <<= log2base
            ret += digit
        return ret
    

    然后表示为二进制字符串,您可以这样做:

    print('{:0b}'.format(to_int(digits=(981, 5, 0, 1001))))
    print('{:0b}'.format(to_int2(digits=(981, 5, 0, 1001))))
    

    结果对两者都相同(我假设最左边是最重要的'digit';否则你必须 reverse 'digits'的顺序):

    1111010101000000010100000000001111101001
    

    (读取输入和减法应该是直接的 . )


    对于你添加的例子,这将是这样的:

    x = to_int2(digits=(6, 15), log2base=4)
    y = to_int2(digits=(2, 7), log2base=4)
    
    print(x, y) # 111 39
    diff = x-y
    print('{:08b}'.format(diff))         # 01001000
    print('{:08b}'.format(-diff & 0xff)) # 10110111
    

    如果你需要动态获取格式和掩码,你可以尝试这样的事情:

    d = 111-39
    bit_length = max(int.bit_length(d), int.bit_length(-d))
    fmt = '{{:0{}b}}'.format(bit_length+1)
    mask = (1<<bit_length+1) - 1
    print(fmt.format(d))
    print(fmt.format(-d & mask))
    

    不确定是否能正确覆盖所有边缘情况......但我相信你从那里就可以了!

  • 1

    你可以消除 pow

    x = 0
    i = 1
    while i <= digitsX:
        x *= base
        x += int(numbersX[i])
        i += 1
    

相关问题