2016-09-27 322 views
1

我需要编写一个Python脚本,它将基数10中的x转换为二进制数,并在小数点后最多包含n个值。我不能只使用bin(x)!下面是我有:将十进制转换为二进制的Python代码

def decimal_to_binary(x, n): 
    x = float(x) 
    test_str = str(x) 
    dec_at = test_str.find('.') 

    #This section will work with numbers in front of the decimal 
    p=0 
    binary_equivalent = [0] 
    c=0 
    for m in range(0,100): 
     if 2**m <= int(test_str[0:dec_at]): 
      c += 1 
     else: 
      break 

    for i in range(c, -1, -1): 
     if 2**i + p <= (int(test_str[0:dec_at])): 
      binary_equivalent.append(1) 
      p = p + 2**i 
     else: 
      binary_equivalent.append(0) 
    binary_equivalent.append('.') 

    #This section will work with numbers after the decimal 
    q=0 
    for j in range(-1, -n-1, -1): 
     if 2**j + q <= (int(test_str[dec_at+1:])): 
      binary_equivalent.append(1) 
      q = q + 2**j 
     else: 
      binary_equivalent.append(0) 

    print float((''.join(map(str, binary_equivalent)))) 

所以说,你叫由decimal_to_binary功能(123.456,4)应该转换123.456与小数点后4位,产生1111011.0111为二进制。

第一部分是细 - 将采取的数字在小数点的前面,在这种情况下123,并且将其转换为二进制,输出1111011

然而,第二部分,其之后的与值涉及十进制,不是在做我认为应该做的事。它给出的输出不是.0111,而是.1111

我用笔和纸运行代码,记下每个变量的值,它应该可以工作。但事实并非如此。谁能帮我解决这个问题吗?

我所说的功能decimal_to_binary(123.456,4),并打印出1111011.1111

回答

0

你靠近,但是当你超越小数有一个问题,你的比较:

if 2**j + q <= (int(test_str[dec_at+1:])): 

你在这里做的是将一个小数值(因为j总是负值)与一个整数值的值进行比较。出于所有实际目的,这种比较将始终如此。

基于周围的逻辑,我的猜测是你试图在这里将它与实际的十进制值进行比较。使用你的数据,这将是0.4在第一次循环,所以你希望进行评估的声明为:

0.5 <= 0.4 

在你的代码中实际的比较是:

0.5 <= 4 

有两个单独的问题这里:

  1. 您正在采取小数点后的所有数字,但实际上并没有在提取中包含小数点本身。这主要是你错误地在你的测试中得到整数的原因。这只是简单地通过参考test_str[dec_at:]而不是test_str[dec_at+1:]
  2. 您正在铸造为int。即使您在第一个点应用了更改,您的代码仍然无法正常运行。但是,在这种情况下,这将是因为在每次迭代中,演员阵列都会将值截断为0。转换为浮动改为:float(test_str[dec_at:])

你比较行因此成为if 2**j + q <= (float(test_str[dec_at:])):,它提供了我的机器上正确的输出。

请注意,浮点比较在某些情况下可能会“挑剔”,具体取决于四舍五入等。如果需要,有ways to mitigate this

+0

哦,好痛心。这是一个很简单的错误......非常感谢你! – dvanny