Complete implementation of Python hexadecimal conversion – 2/10/16 hexadecimal original/complement conversion

1. Several situations that need to be converted

Unsigned integer Binary Decimal Hexadecimal
binary bin2dec() bin2hex()
decimal dec2bin() dec2hex()
hexadecimal hex2bin() hex2dec()

The signed bit, that is, the binary system is expressed in two’s complement.

signed integer 2 base 10 base 16 Hexadecimal
binary signed_bin2dec() signed_bin2hex ()
decimal signed_dec2bin() signed_dec2hex()
hexadecimal signed_hex2bin() signed_hex2dec()

Note: Octal is ignored here because it is rarely used.

Implementation effect of some functions (myBin2dec2hex is a self-compiled module, which does not use any third-party library):

Complete implementation of Python base conversion -0

2. Python’s own base conversion function

1.1 bin (integer)

Enter an integer, which can be accompanied by a string, and any underscore _ can be added between the numbers.

Adding underscores between numbers is a new feature of Python3. Note that underscores can only be added between numbers, and an error will be reported at the beginning and end, and two consecutive underscores_ cannot appear. Other base numbers also follow this rule, which is also in line with people habit of daily use.

Output a binary string with 0b in front of the string.

Note: 1. Negative numbers input in bin() cannot be converted, only a negative sign will be added; 2. An error will be reported when decimals are input

Complete implementation of Python base conversion-1

1.2 int(2/10/16 hexadecimal number/string, base = 2/10/16)

There are various usages of int as follows.

1.2.1 int(decimal number/string)

The default base = 10 can be omitted, this usage has nothing to do with base conversion.

Function 1: Convert decimal integer strings (with plus and minus signs, and any underscore _ between numbers) into integers, decimal strings are not acceptable.

Function 2: Round the decimal number (with plus or minus sign), and the decimal part will be discarded.

Complete implementation of Python base conversion-2

1.2.2 int(binary string, base = 2)

Discovery: Python regards 0b1100 as a number, which is completely equivalent to the integer 12, and can be signed like 12.

When adding base=2, the first argument must be a string. That is, int (binary string, base = 2) is a fixed usage. Strings with or without 0b have the same effect, and can also have positive and negative signs, and any underscore _ can be added between numbers.

Complete implementation of Python base conversion-3

1.2.3 int(hexadecimal string, base = 16)

Analogy 1.2.2, the usage of hexadecimal and binary for int() is the same.

Python regards 0xFF as a number, which is completely equivalent to 255, with positive and negative signs, and letters are not case-sensitive.

When adding base = 16, the first parameter must be a string, so int (hexadecimal string, base = 16) is also a fixed usage. Strings with or without 0x have the same effect, are not case-sensitive, can also have positive and negative signs, and can add any underscore _ between numbers.

Complete implementation of Python base conversion-4

1.3 hex (integer)

The use of hex() and bin() is exactly the same. Enter an integer, with a plus or minus sign, and any underscore _ can be added between the numbers. Outputs a hexadecimal string, prefixed with 0x.

Note: 1. Negative numbers cannot be converted, and the negative sign will be preserved. 2. If decimals cannot be entered, an error will be reported.

Complete implementation of Python base conversion-5

3. Self-compiled function without sign bit to realize base conversion

3.1 bin2dec ()– binary string without sign -> decimal integer

<span style="color:#333333"><span style="background-color:#f9f5e9"><code class="language-python">def bin2dec(bin_str: str) -> int:
    '''
    Function function: binary string without sign -> decimal integer\\

    Input: Binary string, with positive and negative signs, 0b, any number of \\
 and spaces can be added before and after, and an underscore\\
 can be added between numbers
    Output: Decimal integer, only negative sign is reserved, positive sign is not reserved
    '''
    return int(bin_str. strip(), base = 2)
</code></span></span>

3.2 bin2hex() — Binary string without sign bit -> Hexadecimal string without sign bit

<span style="color:#333333"><span style="background-color:#f9f5e9"><code class="language-python">def bin2hex(bin_str: str, hex_width :int = -1) -> str:
    '''
    Function function: binary string without sign bit -> hexadecimal string without sign bit\\

    Input parameter 1: Binary string, with positive and negative signs, 0b, any number of \\
 and spaces can be added before and after, and an underscore\\
 can be added between numbers
    Input parameter 2: optional, hexadecimal string width, if the actual output width > this parameter, warn and output as it is; if the actual output width <= this parameter, add some 0\\

    Output: Hexadecimal string, only negative sign is reserved, positive sign is not reserved
    '''
    new_bin_str = bin_str. strip()
    if (new_bin_str[0] == ' + ' or new_bin_str[0] == '-'): # remove sign
        new_bin_str = new_bin_str[1:]
    if (new_bin_str[:2] == '0b'):
        new_bin_str = new_bin_str[2:]
    hex_str = hex(int(new_bin_str, base = 2))[2:]
    if (hex_width == -1):
        pass
    elif (hex_width < len(hex_str)): # When the bit width is smaller than the actual hexadecimal bit width
        print('bit width parameter' + str(hex_width) + ' < binary' + bin_str + 'output hexadecimal' + '0x' + hex_str
             + 'actual bit width' + str(len(hex_str)) + ', please correct the bit width parameter')
    else:
        hex_str = '0' * (hex_width - len(hex_str)) + hex_str # extended bit complement 0
    if (bin_str[0] == '-'):
        return '-' + '0x' + hex_str
    else:
        return '0x' + hex_str
</code></span></span>

3.3 dec2bin() — decimal integer/string -> binary string without sign bit

<span style="color:#333333"><span style="background-color:#f9f5e9"><code class="language-python">def dec2bin(dec_num: int, bin_width :int = -1) -> str:
    '''
    Function function: decimal integer/string -> binary string without sign bit\\

    Input parameter 1: Decimal integer/string, with positive and negative signs, any number of \\
 and spaces can be added before and after, and an underscore\\
 can be added between numbers
    Input parameter 2: optional, binary string width, if the actual output width > this parameter, a warning will be output as it is; if the actual output width <= this parameter, some 0's will be added to the high bits\\

    Output: Hexadecimal string, only negative sign is reserved, positive sign is not reserved
    '''
    input_dec_num = dec_num
    if (type(dec_num) == str):
        dec_num = int(dec_num. strip())
    old_bin_str = bin(dec_num)
    if (old_bin_str[0] == '-'):
        bin_str = old_bin_str[3:]
    else:
        bin_str = old_bin_str[2:]
    if (bin_width == -1):
        pass
    elif (bin_width < len(bin_str)):
        print('bit width parameter' + str(bin_width) + '<decimal' + str(input_dec_num) + 'output binary' + old_bin_str
             + 'minimum required bit width' + str(len(bin_str)) + ', please correct the bit width parameter')
    else:
        bin_str = '0' * (bin_width - len(bin_str)) + bin_str
    if (old_bin_str[0] == '-'):
        return '-0b' + bin_str
    else:
        return '0b' + bin_str
</code></span></span>

3.4 dec2hex() — decimal integer/string -> hexadecimal string without sign bit

<span style="color:#333333"><span style="background-color:#f9f5e9"><code class="language-python">def dec2hex(dec_num: int , hex_width: int = -1) -> str:
    '''
    Function function: decimal integer/string -> hexadecimal string without sign bit\\

    Input parameter 1: Decimal integer/string, with positive and negative signs, any number of \\
 and spaces can be added before and after, and underscore\\
 can be added between numbers
    Input parameter 2: optional, hexadecimal string width, if the actual output width > this parameter, warn and output as it is; if the actual output width <= this parameter, add some 0\\

    Output: Hexadecimal string, only negative sign is reserved, positive sign is not reserved
    '''
    old_hex_str = bin2hex(dec2bin(dec_num))
    if (old_hex_str[0] == '-'):
        hex_str = old_hex_str[3:]
    else:
        hex_str = old_hex_str[2:]
    if (hex_width == -1):
        pass
    elif (hex_width < len(hex_str)):
        print('bit width parameter' + str(hex_width) + ' < decimal' + str(dec_num) + 'output hexadecimal' + old_hex_str
             + 'actual bit width' + str(len(hex_str)) + ', please correct the bit width parameter')
    else:
        hex_str = '0' * (hex_width - len(hex_str)) + hex_str
    if (old_hex_str[0] == '-'):
        return '-0x' + hex_str
    else:
        return '0x' + hex_str
</code></span></span>

3.5 hex2dec() – unsigned hexadecimal string -> decimal integer

<span style="color:#333333"><span style="background-color:#f9f5e9"><code class="language-python">def hex2dec(hex_str: str) -> int:
    '''
    Function function: hexadecimal string without sign -> decimal integer\\

    Input: Hexadecimal string, with positive and negative signs, any number of \\
 and spaces can be added before and after, and an underscore\\
 can be added between numbers
    Output: Decimal integer, only negative sign is reserved, positive sign is not reserved
    '''
    return int(hex_str. strip(), base = 16)
</code></span></span>

3.6 hex2bin() — unsigned hexadecimal string -> unsigned binary string

<span style="color:#333333"><span style="background-color:#f9f5e9"><code class="language-python">def hex2bin(hex_str: str, bin_width = -1) -> str:
    '''
    Function function: hexadecimal string without sign bit -> binary string without sign bit\\

    Input: Hexadecimal string, with positive and negative signs, any number of \\
 and spaces can be added before and after, and an underscore\\
 can be added between numbers
    Input parameter 2: optional, binary string width, if the actual output width > this parameter, a warning will be output as it is; if the actual output width <= this parameter, some 0's will be added to the high bits\\

    Output: Binary string, only negative sign is reserved, positive sign is not reserved
    '''
    old_bin_str = dec2bin(hex2dec(hex_str))
    if (old_bin_str[0] == '-'):
        bin_str = old_bin_str[3:]
    else:
        bin_str = old_bin_str[2:]
    if (bin_width == -1):
        pass
    elif (bin_width < len(bin_str)):
        print('bit width parameter' + str(bin_width) + ' < hexadecimal' + hex_str + 'output binary' + old_bin_str
             + 'actual bit width' + str(len(bin_str)) + ', please correct the bit width parameter')
    else:
        bin_str = '0' * (bin_width - len(bin_str)) + bin_str
    if (old_bin_str[0] == '-'):
        return '-0b' + bin_str
    else:
        return '0b' + bin_str
</code></span></span>

4. Self-compiled function with sign bit to realize base conversion

4.1 signed_bin2dec ()– 2’s complement string -> decimal integer

<span style="color:#333333"><span style="background-color:#f9f5e9"><code class="language-python">def signed_bin2dec(bin_str: str) -> int:
    '''
    Function function: 2-complement code string -> decimal integer\\

    Input: 2-complement code string, no positive and negative signs, any number of \\
 and spaces can be added before and after, and underscores\\
 can be added between numbers
    Output: Decimal integer, only negative sign is reserved, positive sign is not reserved
    '''
    bin_str = bin_str. strip()
    if (bin_str[:2] == '0b'):
        if (bin_str[2] == '_'):
            bin_str = bin_str[3:]
        else:
            bin_str = bin_str[2:]
    if (bin_str[0] == '_'):
        int ('input ' + bin_str + ' is invalid, the first character cannot be an underscore and two consecutive underscores are not allowed')
    elif (bin_str[0] == '0'):
        return int(bin_str, base = 2)
    elif (bin_str[0] == '1'):
        a = int(bin_str, base = 2) # This statement checks whether the input is legal
        bin_str = bin_str.replace('_', '')
        return a - 2**len(bin_str)
    else:
        int('Input ' + bin_str + ' is illegal, must be 2's complement, no plus or minus signs are allowed')
</code></span></span>

4.2 signed_bin2hex() — 2’s complement string -> 16’s complement string

<span style="color:#333333"><span style="background-color:#f9f5e9"><code class="language-python">def fourBin2OneHex(four_bin: str) -> str:
    '''
    Function function: 4-digit binary string -> 1-digit hexadecimal string\\

    Input: 4-digit binary string, input range 0000~1111\\

    Output: 1-digit hexadecimal string
    '''
    if (four_bin == '0000'):
        return '0'
    elif (four_bin == '0001'):
        return '1'
    elif (four_bin == '0010'):
        return '2'
    elif (four_bin == '0011'):
        return '3'
    elif (four_bin == '0100'):
        return '4'
    elif (four_bin == '0101'):
        return '5'
    elif (four_bin == '0110'):
        return '6'
    elif (four_bin == '0111'):
        return '7'
    elif (four_bin == '1000'):
        return '8'
    elif (four_bin == '1001'):
        return '9'
    elif (four_bin == '1010'):
        return 'a'
    elif (four_bin == '1011'):
        return 'b'
    elif (four_bin == '1100'):
        return 'c'
    elif (four_bin == '1101'):
        return 'd'
    elif (four_bin == '1110'):
        return 'e'
    elif (four_bin == '1111'):
        return 'f'
    else:
        int('Enter binary characters' + four_bin + 'error, binary can only contain 0 or 1')

def signed_bin2hex(bin_str: str, hex_width: int = -1) -> str:
    '''
    Function: 2-complement string -> 16-complement string\\

    Input parameter 1: 2-complement code string, no positive and negative signs, any number of \\
 and spaces can be added before and after, and underscores\\
 can be added between numbers
    Input parameter 2: Optional, the width of a hexadecimal complement string, if the actual output width > this parameter, a warning will be output as it is; if the actual output width <= this parameter, a number of sign bits will be added to the high bit\\

    Output: Hexadecimal complement string
    '''
    input_bin_str = bin_str
    bin_str = bin_str. strip()
    if (bin_str[:2] == '0b'): # Binary string starts with 0b
        bin_str = bin_str[2:]
    elif (bin_str[0] == '0' or bin_str[0] == '1'):
        pass
    else:
        int('Input ' + bin_str + ' is invalid, the input must be two’s complement, plus and minus signs are not allowed and the first character cannot be an underscore')
    # Check whether the input is legal, the last character cannot be an underscore and there cannot be two consecutive underscores
    if (bin_str[-1] == '_' or '__' in bin_str):
        int('Input ' + bin_str + ' is invalid, the last character cannot be an underscore and there cannot be two consecutive underscores')
    else:
        bin_str = bin_str.replace('_', '') # Remove the underscore if the input is legal
    # Remove the redundant sign bit in front of the 2's complement string, and keep two bits
    for i in range(len(bin_str)-1):
        if (bin_str[i + 1] == bin_str[0]):
            if (i + 1 == len(bin_str)-1):
                bin_str = bin_str[i:]
            else:
                continue
        else:
            bin_str = bin_str[i:]
            break
    if (len(bin_str) % 4 > 0): # Complement the sign bit to a multiple of 4
        bin_str = bin_str[0] * (4 - len(bin_str) % 4) + bin_str
    hex_str = ''
    for i in range(int(len(bin_str)/4)):
        hex_str + = fourBin2OneHex(bin_str[i*4 : i*4 + 4])
    if (hex_width == -1):
        pass
    elif (hex_width < len(hex_str)):
        print('bit width parameter' + str(hex_width) + ' < 2-complement code' + input_bin_str + 'output 16-complement code'
             + '0x' + hex_str + 'actual bit width' + str(len(hex_str)) + ', please correct the bit width parameter')
    else:
        if (hex_str[0] in ['0', '1', '2', '3', '4', '5', '6', '7']):
            hex_str = '0' * (hex_width - len(hex_str)) + hex_str
        else:
            hex_str = 'f' * (hex_width - len(hex_str)) + hex_str
    return '0x' + hex_str
</code></span></span>

4.3 signed_dec2bin() — Decimal number/string -> 2’s complement string

<span style="color:#333333"><span style="background-color:#f9f5e9"><code class="language-python">def signed_dec2bin(dec_num: int, bin_width: int = -1) -> str:
    '''
    Function function: Decimal number/string -> 2's complement string\\

    Input parameter 1: Decimal number/string, with positive and negative signs, any number of \\
 and spaces can be added before and after, and an underscore\\
 can be added between numbers
    Input parameter 2: optional, two-complement code string width, if the actual output width > this parameter, a warning will be output as it is; if the actual output width <= this parameter, a number of sign bits will be added to the high bit\\

    Output: 2's complement string
    '''
    dec_num_str = str(dec_num)
    if (type(dec_num) == str):
        dec_num = int(dec_num. strip())
    if (dec_num == 0):
        bin_str = '0'
    elif (dec_num > 0):
        bin_str = '0' + bin(dec_num)[2:] # complement sign bit 0
    else:
        for i in range(10000):
            if (2**i + dec_num >= 0):
                bin_str = bin(2**(i + 1) + dec_num)[2:] # The complement of a negative number num is equal to (2**i + dec_num)
                break
    if (bin_width == -1):
        pass
    elif (bin_width < len(bin_str)):
        # If the actual bit width is greater than the set bit width, a warning will be reported, and then output according to the actual bit width
        print('bit width parameter' + str(bin_width) + ' < decimal' + dec_num_str + 'output 2's complement'
             + '0b' + bin_str + 'actual bit width' + str(len(bin_str)) + ', please correct the bit width parameter')
    else:
        bin_str = bin_str[0] * (bin_width - len(bin_str)) + bin_str # If the actual bit width is less than the set bit width, then the sign bit will be complemented
    return '0b' + bin_str
</code></span></span>

4.4 signed_dec2hex() — decimal number/string -> hexadecimal complement string

<span style="color:#333333"><span style="background-color:#f9f5e9"><code class="language-python">def signed_dec2hex(dec_num: int, hex_width = -1) -> str:
    '''
    Function function: decimal number/string -> hexadecimal complement string\\

    Input parameter 1: Decimal number/string, with positive and negative signs, any number of \\
 and spaces can be added before and after, and an underscore_\\
 can be added between numbers
    Input parameter 2: Optional, the width of a hexadecimal complement string, if the actual output width > this parameter, a warning will be output as it is; if the actual output width <= this parameter, a number of sign bits will be added to the high bit\\

    Output: Hexadecimal complement string
    '''
    hex_str = signed_bin2hex(signed_dec2bin(dec_num))[2:]
    if (hex_width == -1):
        pass
    elif (hex_width < len(hex_str)):
        print('bit width parameter' + str(hex_width) + ' < decimal' + str(dec_num) + 'output hexadecimal complement' + '0x' +
            hex_str + 'actual bit width' + str(len(hex_str)) + ', please correct the bit width parameter')
    else:
        if (hex_str[0] in ['0', '1', '2', '3', '4', '5', '6', '7']):
            hex_str = '0' * (hex_width - len(hex_str)) + hex_str
        else:
            hex_str = 'f' * (hex_width - len(hex_str)) + hex_str
    return '0x' + hex_str
</code></span></span>

4.5 signed_hex2bin() — hexadecimal complement string -> 2-ary complement string

<span style="color:#333333"><span style="background-color:#f9f5e9"><code class="language-python">def oneHex2fourBin(one_hex: str) -> str:
    '''
    Function function: 1-digit hexadecimal string -> 4-digit binary string\\

    Input: 1-digit hexadecimal string, input range 0~9, a~f or A~F\\

    Output: 4-digit binary string
    '''
    if (one_hex == '0'):
        return '0000'
    elif (one_hex == '1'):
        return '0001'
    elif (one_hex == '2'):
        return '0010'
    elif (one_hex == '3'):
        return '0011'
    elif (one_hex == '4'):
        return '0100'
    elif (one_hex == '5'):
        return '0101'
    elif (one_hex == '6'):
        return '0110'
    elif (one_hex == '7'):
        return '0111'
    elif (one_hex == '8'):
        return '1000'
    elif (one_hex == '9'):
        return '1001'
    elif (one_hex == 'a' or one_hex == 'A'):
        return '1010'
    elif (one_hex == 'b' or one_hex == 'B'):
        return '1011'
    elif (one_hex == 'c' or one_hex == 'C'):
        return '1100'
    elif (one_hex == 'd' or one_hex == 'D'):
        return '1101'
    elif (one_hex == 'e' or one_hex == 'E'):
        return '1110'
    elif (one_hex == 'f' or one_hex == 'F'):
        return '1111'
    else:
        int('Enter hex characters' + one_hex + 'error, hex can only contain 0~9, a~f or A~F')

def signed_hex2bin(hex_str: str, bin_width: int = -1) -> str:
    '''
    Function function: hexadecimal complement string -> 2-ary complement string\\

    Input parameter 1: Hexadecimal complement string, no positive and negative signs, any number of \\
 and spaces can be added before and after, and an underscore\\
 can be added between numbers
    Input parameter 2: optional, two-complement code string width, if the actual output width > this parameter, a warning will be output as it is; if the actual output width <= this parameter, a number of sign bits will be added to the high bit\\

    Output: 2's complement string
    '''
    input_hex_str = hex_str
    hex_str = hex_str. strip()
    # Check whether the input is legal, positive and negative signs are not allowed, the beginning and the end cannot be underscores, and two consecutive underscores cannot appear
    if (hex_str[0] in [' + ', '-', '_'] or hex_str[-1] == '_' or '__' in hex_str):
        int('input' + input_hex_str + ' is invalid, it must be hexadecimal complement code, no sign is allowed, '
             + 'The beginning and end cannot be underscores, and there cannot be two consecutive underscores')
    elif (hex_str[:2] == '0x'):
        hex_str = hex_str[2:]
    hex_str = hex_str.replace('_', '') # Remove the underscore if the input is legal
    bin_str = ''
    for i in hex_str:
        bin_str += oneHex2fourBin(i)
    # Remove the redundant sign bit in front of the 2-complement string, and keep two bits
    for i in range(len(bin_str)-1):
        if (bin_str[i + 1] == bin_str[0]):
            if (i + 1 == len(bin_str)-1):
                bin_str = bin_str[i:]
            else:
                continue
        else:
            bin_str = bin_str[i:]
            break
    if (bin_str == '00'):
        bin_str = '0'
    if (bin_width == -1):
        pass
    elif (bin_width < len(bin_str)):
        # If the actual bit width is greater than the set bit width, a warning will be reported, and then output according to the actual bit width
        print('bit width parameter' + str(bin_width) + ' < 16-complement code' + input_hex_str + 'output 2-complement code'
             + '0b' + bin_str + 'actual bit width' + str(len(bin_str)) + ', please correct the bit width parameter')
    else:
        bin_str = bin_str[0] * (bin_width - len(bin_str)) + bin_str # If the actual bit width is less than the set bit width, then the sign bit will be complemented
    return '0b' + bin_str
</code></span></span>

4.6 signed_hex2dec() — hexadecimal complement string -> decimal integer

<span style="color:#333333"><span style="background-color:#f9f5e9"><code class="language-python">def signed_hex2dec(hex_str: str) -> int:
    '''
    Function function: hexadecimal complement string -> decimal integer\\

    Input: Hexadecimal complement string, no positive and negative signs, any number of \\
 and spaces can be added before and after, and an underscore\\
 can be added between numbers
    Output: Decimal integer, only negative sign is reserved, positive sign is not reserved
    '''
    return signed_bin2dec(signed_hex2bin(hex_str))
</code></span></span>

4. Import self-edited modules

See my other blog, how Python imports py files written by itself

5. Hexadecimal conversion module and its test jupter notebook document sharing

I put all the above conversion functions into the bin2dec2hex.py file, as well as the documents for testing, and put them together in my code cloud open source warehouse. If you need it, you can go to the following link to get it yourself:

Python self-compiled modules: Python modules written by myself to implement some small and practical functions and improve work efficiency

Complete realization of Python base conversion – 2/10/16 base original/complement conversion_python bin2dec_Xu Xiaokang’s Blog Blog-CSDN Blog