使用Python将二进制转换为十进制(不使用内置的二进制函数)

3

好的,这是我在这里发的第一篇帖子,如果问题无法解决,请原谅和忽略;

背景: 我正在学习计算机科学160课程。自高中以来,我没有上过任何与计算机相关的课程,所以加入这个班对我来说是一个很大的转变。所有东西都看起来非常先进。我们一直在使用Python,并且每周都要写一个程序。

我已经研究了一个星期,甚至开始都很困难。 提示是读取只包含1和0的整数,逐位处理二进制数字并报告十进制等价物。现在,我从一位同学那里得到了一些提示,至少让我朝着一个方向前进。

设置几个计数器; 使用%运算符检查数字除以2的余数,并切掉最后一个数字(向右)以继续并处理下一个数字。

我非常难以理解应该在二进制数字本身上使用哪个公式将数字转换为十进制。

setbitval = 0
counter = 0

user = int(input("enter a binary value. "))

if user % 2 == 1:
        user = (user/10) - .1
        setbitval += 1

这是我目前为止的所有内容...我的思维正在阻碍我。我已经搜索了很多,甚至通过这些论坛。

非常感谢任何信息或想法,
T

编辑:好吧,各位的帮助都非常有用,但我有一个问题,就是如何检查用户输入是否不是二进制数。

for i in reversed(bits):   
decimal += 2**counter * int(i)

counter += 1    

这是这里的某个人给我的公式,我一直在尝试不同的迭代方式,例如 "for i in bits: if i in bits: != 0 or 1" 和 "if i in bits: >= 1 or <=0"。
有什么想法吗?

2
那么你不能只是这样做DecValue= int(input("enter a binary value. "), 2)吗? - NendoTaka
或者像将整数转换为字符串,反转它,并在迭代过程中添加逐渐增加的二次幂一样。 - Sam van Kampen
@NendoTaka 我从那段代码中理解到的是用户输入将会是二进制?这样做有什么作用呢? 感谢您的评论。Sam van,这个概念确实让我想起了一些在论坛中发现的东西。但是单独处理每个数字并对它们进行操作仍然是一个谜团。非常感谢你们两个;感觉自己已经进入了“为我编写此代码”的领域。基本上我不得不自学基础知识..再次感谢 - relytkadReh
@SamvanKampen 抱歉,我也想提到你。谢谢。 - relytkadReh
4个回答

1
要将二进制值转换为十进制,您需要执行以下操作:
取最低有效位并乘以2^0,然后取下一个最低有效位并乘以2^1,接下来的每个数乘以2^2等等...
例如,假设您需要将数字1010转换为十进制:
您将有0*2^0 + 1*2^1 + 0*2^2 + 1*2^3 = 0 + 2 + 0 + 8 = 10
因此,在Python代码中,您需要:
读取用户输入的int(表示二进制值)。
将该int转换为字符串,以便您可以将其分解为数字列表。
从您创建的字符串中创建数字列表(在Python中,可以从字符串而不是int创建数字列表,这就是为什么您首先需要进行转换的原因)。
倒序遍历位列表,并将每个位乘以2^k,其中k是从0开始的计数器。
以下是演示我刚才尝试解释的代码:
user_input = int(input("enter a binary value"))

bits = list(str(user_input))

decimal = 0

counter = 0

for i in reversed(bits):
    decimal += 2**counter * int(i)
    counter+=1

print 'The decimal value is: ', decimal

你好,感谢评论。我不得不将raw_input更改为我的Python版本中的input。将位反转以便我们可以更轻松地操作它们?然后循环会添加"(2的counter次幂乘以用户的二进制值)"? - relytkadReh
当你将二进制转换为十进制时,公式是2^0bit_val(0或1) + 2^1bit_val + 2^2*bit_val...其中你从最后一位开始取,然后从右到左依次取下一位,直到第一位。这就是为什么你需要反转比特位。所以,你需要获取用户输入,生成一个比特列表,然后反转该列表并应用上述公式...最后一位表示十进制中的0或1,从右到左的下一位表示十进制中的2或0,下一位表示4或0,下一位表示8或0等等。当你将所有这些值相加时,你就得到了该值的十进制表示。 - user3362334
感谢您详细阐述这种方法。现在我感觉不再像之前那样孤立无援了。听起来制作一个列表可以将位分离,以便可以单独操作它们。 - relytkadReh
那就是我的想法。我很高兴能够帮助。 - user3362334

1
你可以使用这段代码:
binary= raw_input("Binary: ")
d= int(binary, 2)
print d

谢谢您的回复!我现在认为我可以理解您的代码,但我也不认为我的导师会接受只有三行代码。在这里聊天后,我想我有一个将所有内容组合起来的想法,但我必须解释这个方法并使用更详细的公式。您的代码是说“存储用户的字符串,然后将该字符串转换为二进制整数?” - relytkadReh
是的,如果你输入一串二进制数字并将其转换为十进制,你可以添加一个循环来转换多个数字。 - apk

0
我建议阅读维基百科上的以下文章: https://en.wikipedia.org/wiki/Radix https://en.wikipedia.org/wiki/Binary_number 第一篇文章可以让你了解数字系统的工作原理,第二篇文章则解释并展示了在二进制和十进制系统之间进行转换的公式。 阅读完后尝试实现解决方案。这就是我处理这个问题时所做的。如果这不起作用,请告诉我,我会发布代码。
希望这段代码能够澄清一些事情。
x = input("Enter binary number: ").strip()
decimal = 0
for i in range(len(x)):
    decimal += int(x[i]) * 2**abs((i - (len(x) - 1)))
print(decimal)

该代码接受一个二进制字符串作为输入,将其转换为十进制数并输出为整数。具体过程如下:
二进制数的第1个元素*2^(二进制数长度-1)
二进制数的第2个元素*2^(二进制数长度-2)
以此类推直到最后一个元素和...2^0
如果我们取数字10011,则使用此公式进行转换如下: 1*2^4 + 0*2^3 + 0*2^2 + 1*2^1 + 1*2^0,等于19。
但是,请注意,此代码假定二进制数是有效的。如果有帮助,请告诉我。
使用while循环的另一种实现可能如下所示。也许比使用for循环的代码更容易理解。
x = input("Enter binary number: ").strip()
decimal = 0
index = 0
exp = len(x) - 1
while index != len(x):
    decimal += int(x[index]) * 2**exp
    index += 1
    exp -= 1
print(decimal)

在这个例子中,我们从最高位数的数字开始,也就是二进制数长度减一,循环遍历整个数字,降低幂次并变更索引。

如何检查数字是否为二进制数? 尝试使用辅助函数来确定数字是否为二进制数,然后将此功能插入到您的主函数中。例如:

def is_binary(x):
    """ Returns True if number x is binary and False otherwise.

    input: x as a string
    """
    for i in list(x):
        if i not in ["1", "0"]:
            return False
    return True


def binary_decimal(x):
    """ Converts binary to decimal.
    input: binary number x as a string
    output: decimal number as int
    """
    if not is_binary(x):
        return "Number is invalid"
    decimal = 0
    for i in range(len(x)):
        decimal += int(x[i]) * 2**abs((i - (len(x) - 1)))
    return decimal

第一个函数检查数字是否仅由1和0组成,第二个函数只有在根据第一个函数判断为二进制时才转换您的数字。 如果您希望在数字不是二进制时引发错误而不是仅打印消息,则还可以尝试使用assert语句或try / except。 当然,您也可以不使用任何函数来实现此解决方案。

感谢评论和链接。如果您发布代码,现在可能清楚地表明,它对我没有太大好处,除了复制和粘贴。再次感谢您,我将阅读维基页面。 - relytkadReh
所以我遇到了之前找到的转换为十进制的公式。前几天,我迷失在尝试使用用户输入的“len()”和模拟转换公式中。这太压抑了。 - relytkadReh
我在检查用户输入是否为二进制时遇到了麻烦。在公式之前有没有一种实现的方式? - relytkadReh
我添加了一些带有描述的代码。如果有帮助,请告诉我。 - Vlad

0

我会同意这接近于“为我编写代码”的领域,但我会试着以一种方式回答您,使您走上正确的轨道,而不仅仅是发布一个工作的代码片段。

做这件事的简单方法就是使用int()的基本参数,但我猜想那是被禁止的。

您已经有了一种测试问题中当前位的方法,即检查是否n % 2 == 1。如果是这种情况,我们需要增加2的幂次。

然后,我们需要某种方式去到下一位。在二进制中,我们将使用位移,但可悲的是,我们没有它们。a >> b等同于a // (2**b) - 您能写出其十进制等效形式吗?

您还需要保持当前位表示的2的幂的计数器、循环和某种检测结束条件的方式。这些作为读者的练习留给了。


谢谢Sam;那个公式会取用户的二进制值,除以“(2的B次方)”,对吗? 而B将是我设置的某种计数器?即我所指的位和要使用的2的幂次方? - relytkadReh
当一个位测试为正(例如 n % 2 == 1),您想要将正确的二次幂添加到十进制值中。这意味着您需要在某个变量中跟踪当前的二次幂。然后,您想要继续下一个位(例如 1001 应该变成 100)。为了做到这一点,您需要执行类似于位移的操作,但是在十进制中。 - Sam van Kampen
谢谢Kampen。看起来在Python中没有位移操作符,所以需要想出一些模拟的方法。干杯! - relytkadReh

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