"""
Integers and bit-manipulation.
Andreas Wachtel, PhD. 2016
"""

import numba as nb

@nb.njit(fastmath=True)
def clear_bit(value, bit):
    return value & ~(1<<bit)


@nb.njit(fastmath=True)
def set_bit(value, bit):
    return value | (1<<bit)


@nb.njit(fastmath=True)
def get_bit(value, bit):
    return 1 if value & (1<<bit) > 0 else 0


def intToBitString( value, bits=60, sep=12 ):
    """returns a string containing bits (60 by default) of a given integer 
    and separated as indicated (every 12 bits by default)."""
    text = ''
    for k in reversed(range(bits)):
        text = text + str(get_bit(value,k))
        if k % sep == 0:
            text += ' '
    return text
    

def bitStringToInt( text ):
    """returns an integer defined by the 20-bit-string (without spaces). The first symbol is the first bit"""
    assert(len(text) == 20), 'String too long'
    res = 0
    for i in range(20):
        if text[i] == '1':
            res = set_bit(res, i)
    return res



if __name__ == '__main__':
    print("This file was executed from the command line or an interpreter.")
    print('The integers 0,1,...,7 as bits.')
    bits = 3
    for f in range(2**bits):
        print( 'f = %2s :  %s' % (f, intToBitString(f, bits)))
    
else:
    print("Import: Integer and bit-manipulation  (AW, 2024)")
