如何获取二进制表示中包含1的数字?

3

我正在尝试在Python中实现快速二进制幂运算。我想知道整数的二进制表示返回 1 的情况。也许通过示例更容易理解:

bin(13) # returns 1101 because one 8 + one 4 + one 1 = 13. 

如何编写一个函数,通过将二进制数作为参数传递,返回8、4和1?如您所见,我并不是在明确地寻求2的幂,而是试图得到能够将这些幂相乘的最简表示。

1
我实际上不懂Python,所以我不会发表答案,但是在C中,您可以执行类似于for(int bit = 1; bit; bit <<= 1)if(number&bit){ /*将位的值附加到数组、字符串或其他*/}的操作,将int替换为数字的任何类型。因此,如果您知道如何在Python中表达它,那就可以了。 - Jason C
这是唯一的方法(好吧,其他方法仍然类似)来简洁地完成它。如果您需要极快的速度,另一个选择可能是预先计算的查找表,其中 bitValues[number] 是给定数字的值数组。但是,如果 number 是 8 位,则只有这种方法是可行的。如果它是 16 位,则由于表的大小,您可能会遇到缓存未命中问题,但您只需进行测试即可。如果是 32 或 64 位,则表太大了,尽管我想您可以将其分成 4/8 个 8 位块。 - Jason C
1
我需要关注我的问题类型的性能,但你确实帮了我 :) - DarkDrassher34
你想做什么,以至于性能重要到足以证明微观优化的必要性,但又不重要到足以证明使用除Python之外的其他东西的必要性?为什么要使用bin(),它只是一个数字的二进制字符串表示?我猜你可能是为了学习而这样做的? - AMC
绝对不是重复的。我不能确切地说我在尝试做什么,但是让我们说我需要Python进行易于使用的集成。我正在学习并且喜欢学习。正如我所说,它与优化指数有关。很多微观优化会导致宏观优化,对吧? ;) - DarkDrassher34
显示剩余3条评论
2个回答

2

这个问题有点令人困惑(请看我的评论),但我还是想分享一个解决方案,因为目前被接受的答案对我来说很难理解。出于好奇心,明天我可能会比较和基准化一堆不同的解决方案。

bin_num = bin(13)

def bin_str_decomp(bin_num_str):
    bin_clean = bin_num_str[:1:-1]
    return [1 << idx for idx, bit in enumerate(bin_clean) if bit == '1']

print(bin_str_decomp(bin_num))

我很喜欢你的解决方案有多干净。做得好。 - DarkDrassher34

1

你可以按照以下方式进行操作:

# Split the binary and grab interested part, and its size.
# >> bin(123456789) == "0b111010110111100110100010101"
binary = bin(123456789)[2:]
size = len(binary)

numbers = []
for i in range(size):
    # Checks to see if the binary[i] is not equals to zero.
    if binary[i] is not "0":
        # Indexes the `binary` string and adds (size - i - 1) zeros to the end of it.
        number = int(binary[i] + "0" * (size - i - 1), 2)
        numbers.append(number)


print(numbers)
# >> [67108864, 33554432, 16777216, 4194304, 1048576, 524288, 131072, 65536, 32768, 16384, 2048, 1024, 256, 16, 4, 1]

这是一个更简短的解决方案,只是为了好玩。

binary = bin(13)[2:]

nums = [
    int(binary[i] + "0" * (len(binary) - i - 1), 2)
    for i in range(len(binary))
    if binary[i] is not "0"
]
return nums

以下是单行解决方案,仅出于好奇。

print((lambda binary: [int(binary[i] + "0" * (len(binary) - i - 1), 2) for i in range(len(binary)) if binary[i] is not "0"])(binary = bin(123456789)[2:]))

评论不适合进行长时间的讨论;此对话已被移至聊天室 - Samuel Liew
1
@SamuelLiew,你是怎么做到的?我很想把评论移到聊天中,或者至少创建一个聊天并导入现有的评论。我猜这是在更高的声望下解锁的功能? - AMC
1
@AlexanderCécile 哎呀,我没注意到你之前已经创建了一个聊天室。不管怎样,当管理员创建一个聊天室时,所有评论者都被授予了聊天的能力,即使他们没有足够的声望。如果下次评论变得太啰嗦了,只需标记该帖子以请求管理员将其移至聊天室即可。 - Samuel Liew

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接