0

I can't figure out why my program doesn't output 128.255.3.15 with an input of 10000000111111110000001100001111.

Code:

#function to read a number

def readNum():

    binary = input("Please enter a 32 digit number: ")
    return binary

#function to check to make sure there are 32 digits

def checkNum(binary):

    while len(binary) != 32:
           flag = 'error'
           return flag
    else:
           flag = 'true'
           return flag

#function to split the number into 4 strings and 8 bits

def splitNum(binary):

    first = binary[0:8]
    second = binary[8:16]
    third = binary[16:24]
    fourth = binary[24:32]
    return [first, second, third, fourth]


#function to check to see if they are all numbers and calculate sum

def calcSum(first):

    decimal = 0
    binary = 0
    digit = 0
    flag = 'true'
    for digit in first:
           try:
                  decimal = int(digit)
           except ValueError:
                  flag = 'error'
                  break;
           else:
                  decimal = decimal*2 + int(digit)
    if flag == 'true':
           return decimal
    else:
           print("Not a valid number.")

#main function

def main():

    flag = 'true'
    myList = []
    binary = readNum()
    flag = checkNum(binary)
    if flag == 'true':
           myList = splitNum(binary)
           part1 = calcSum(myList[0])
           part2 = calcSum(myList[1])
           part3 = calcSum(myList[2])
           part4 = calcSum(myList[3])
           print(part1, ".", part2, ".", part3, ".", part4)
    else:
           print("Not a valid 32 digit number!!")

#call main
main()
Abhishek Bhagate
  • 5,583
  • 3
  • 15
  • 32
Aidhall
  • 11

5 Answers5

1

The problem lies in this line -

decimal = decimal*2 + int(digit)

decimal is initialized to 0, and you are not doing it correctly. You are just adding double of decimal + whatever digit is...which is not correct logic. To convert from binary to decimal, the logic is simple -

  1. Take a binary number. Initialize a variable, say decimal to 0.

  2. Keep adding - (2^position from right starting with 0)*binary digit to decimal.

  3. You get the equivalent decimal. Simple!

I have made changes to your code and it should work fine now -

#function to read a number

def readNum():

    binary = input("Please enter a 32 digit number: ")
    return binary

#function to check to make sure there are 32 digits

def checkNum(binary):

    while len(binary) != 32:
           flag = 'error'
           return flag
    else:
           flag = 'true'
           return flag

#function to split the number into 4 strings and 8 bits

def splitNum(binary):

    first = binary[0:8]
    second = binary[8:16]
    third = binary[16:24]
    fourth = binary[24:32]
    print([first, second, third, fourth])
    return [first, second, third, fourth]


#function to check to see if they are all numbers and calculate sum

def calcSum(first):
    decimal = 0
    tmp =0
    pos = 0
    flag = 'true'
    for digit in first[::-1]:
           try:
                  tmp = int(digit)
                  # Further error/validity checking
                  if tmp != 0 or tmp != 1:  
                      flag = 'error'
                      break
           except ValueError:
                  flag = 'error'
                  break;
           else:
                  decimal += (2**pos)*tmp
           pos+=1
    if flag == 'true':
           return decimal
    else:
           print("Not a valid number.")

#main function

def main():

    flag = 'true'
    myList = []
    binary = readNum()
    flag = checkNum(binary)
    if flag == 'true':
           myList = splitNum(binary)
           part1 = calcSum(myList[0])
           part2 = calcSum(myList[1])
           part3 = calcSum(myList[2])
           part4 = calcSum(myList[3])
           print(part1, ".", part2, ".", part3, ".", part4)
    else:
           print("Not a valid 32 digit number!!")

#call main
main()

OUTPUT :

Please enter a 32 digit number: ['10000000', '11111111', '00000011', '00001111']
128 . 255 . 3 . 15
Abhishek Bhagate
  • 5,583
  • 3
  • 15
  • 32
0

Why don't you simply use int function?

>>> int('100', 2)
4

thus, you can just change your main function to something like this:

def main():
    flag = 'true'
    binary = readNum()
    flag = checkNum(binary)
    if flag == 'true':
        nums = map(lambda num: int(num, 2), splitNum(binary))
        print('.'.join(nums))
    else:
        print("Not a valid 32 digit number!!")
Mohammad Jafari
  • 1,742
  • 13
  • 17
0

That's because your formula for calculating the sum is not correct and you're also overwriting decimal every iteration:

decimal = decimal*2 + int(digit)

0111 = 02^3 + 12^2 + 12^1 + 12^0

There's also another arg you can provide to int() to get what you need ...

int('0111', 2) = 7
ahelium
  • 86
  • 1
  • 5
0

In this block:

       try:
              decimal = int(digit)
       except ValueError:
              flag = 'error'
              break;
       else:
              decimal = decimal*2 + int(digit)

You are resetting decimal every time and then you're adding the digit to double of itself in else block
So you never get anything other than 3 & 0 ( if digit be 1 you get 3 and if digit be 0 you get 0)

You need to store your final result and temporary result in two different variables (or using some more smart mathematical method)

Notes:
1st: try debugging your code in a debugger (e.g. pdb)
2nd: as @ahelium mentioned you can convert binary to decimal directly using int class

Ariyan
  • 14,760
  • 31
  • 112
  • 175
0

This result could be done using bit shifting.

L = []

s = int('10000000111111110000001100001111', 2)

for _ in range(4):
    L.insert(0, s & 0xff)
    s >>= 8

print('.'.join(map(str, L)))

Or, more simply, Convert an IP string to a number and vice versa

from socket import inet_ntoa
from struct import pack

s = int('10000000111111110000001100001111', 2)
print(inet_ntoa(pack('!L',s)))

Prints:

128.255.3.15
Chris Charley
  • 6,403
  • 2
  • 24
  • 26