#!/usr/bin/python3
# -*- coding: utf-8 -*-
import math

def int2bin(val, negConv = 2, nbBits = None):
    negConvs = {-1: "valeur absolue unsigned",
                 0: "bit de signe + valeur absolue",
                 1: "signed complément à un",
                 2: "signed complément à deux"}
    if negConv not in negConvs:
        return "Convention de signe inconnue"
    positive = True
    tmpVal = val
    if (tmpVal == 0):
        return "0"
    if tmpVal < 0:
        positive = False
        tmpVal = -tmpVal
        if negConv == 2:
            bitsMini = math.ceil(math.log(tmpVal, 2))
            if tmpVal == 2**bitsMini:
                bitsMini = bitsMini + 1
            tmpVal = 2**bitsMini - tmpVal
            
    bitList = list()
    while (tmpVal > 0):
        bitList.append(tmpVal % 2)
        tmpVal = tmpVal // 2
    # Convention signée, un positif doit commencer par 0
    if positive and negConv >= 0:
        bitList.append(0)
    else:
        if negConv == 0:
            bitList.append(1)
        elif negConv == 1:
            # Complément à 1 : on inverse tous les bits
            bitList = list(map(lambda x: (x + 1) % 2, bitList))
            if negConv == 1:
                # On doit avoir un 1 en première position
                bitList.append(1)
    bitsSig = len(bitList)   
    if nbBits:
        if len(bitList) > nbBits:
            return "%s ne peut pas se représenter sur %s bits en %s, il faut au moins %s bits" % (val, nbBits, negConvs[negConv], len(bitList))
        elif len(bitList) < nbBits:
            if positive or negConv == -1:
                # Positif : on complète avec des 0
                bitList = bitList + [0]*(nbBits - len(bitList))
            else:
                # Négatif en complément : on complète avec des 1
                if negConv > 0:
                    bitList = bitList + [1]*(nbBits - len(bitList))
                # Négatif en signe + valeur absolue : on décale le 1 initial et on rempli avec des zéros
                else:
                    bitList[len(bitList) - 1] = 0
                    bitList = bitList + [0]*(nbBits - len(bitList))
                    bitList[len(bitList) - 1] = 1
                    
    return "%s en %s : %s (%s bits, %s bits significatifs)" % (val, negConvs[negConv], "".join(map(str, reversed(bitList))), len(bitList), bitsSig)
val = -8
nbBits = 4
print(int2bin(val, -1, nbBits))
print(int2bin(val, -1, 2*nbBits))
print(int2bin(val, 0, nbBits))
print(int2bin(val, 0, 2*nbBits))
print(int2bin(val, 1, nbBits))
print(int2bin(val, 1, 2*nbBits))
print(int2bin(val, 2, nbBits))
print(int2bin(val, 2, 2*nbBits))