def get_exponent(bits):
    """Given a value representing a float (in the machine), return the exponent.
    """
    return ((bits >> 23) & 0xff) def get_mantissa(bits):
    """Given a value representing a float (in the machine), return the mantissa.
    """
    return bits & 0x7fffff def bits2float(bits):
    """Add some Revelation-specific code to bits2float.
    Checks for NaN and INF.
    """
    if is_inf(bits) and (bits >> 31) == 0:
        return float('inf')
    elif is_inf(bits) and (bits >> 31) == 1:
        return float('-inf')
    elif is_nan(bits):
        return float('nan')
    return pydgin.utils.bits2float(bits) def float2bits(flt):
    """Add some Revelation-specific code to float2bits.
    Checks for NaN and INF.
    """
    if math.isnan(flt):
        return float_factory(sign=0, exponent=0xff, mantissa=0x7fffff)
    elif math.isinf(flt) and flt > 0.0:
        return float_factory(sign=0, exponent=0xff, mantissa=0)
    elif math.isinf(flt) and flt < 0.0:
        return float_factory(sign=1, exponent=0xff, mantissa=0)
    elif flt == 0.0:
        return float_factory(sign=0, exponent=0, mantissa=0)
    return pydgin.utils.float2bits(flt) def format_thousands(number):
    """Format a number with a comma after every third digit.
    """
    chars = []
    number_s = str(number)
    size = len(number_s)
    for index in xrange(size - 1, -1, -1):
        if (size - index) > 1 and (size - index - 1) % 3 == 0:
            chars.insert(0, ',')
        chars.insert(0, number_s[index])
    return ''.join(chars) def is_nan(bits):
    return get_exponent(bits) == 0xff and get_mantissa(bits) != 0 def is_inf(bits):
    return get_exponent(bits) == 0xff and get_mantissa(bits) == 0 def is_zero(bits):
    return get_exponent(bits) == 0 and get_mantissa(bits) == 0 def sext_3(value):
    """Sign-extended 3 bit number.
    """
    if value & 0x4:
        return 0xfffffff8 | value
    return value def sext_11(value):
    """Sign-extended 11 bit number.
    """
    if value & 0x400:
        return 0xfffff800 | value
    return value def sext_24(value):
    """Sign-extended 24 bit number.
    """
    if value & 0x800000:
        return 0xff000000 | value
    return value def zfill(string, width):
    """zfill(x, width) -> string
    Pad a numeric string x with zeros on the left, to fill a field
    of the specified width.  The string x is never truncated.
    """
    size = len(string)
    if size >= width: return string
    sign = ''
    if string[0] in ('-', '+'):
        sign, string = string[0], string[1:]
    return sign + '0' * (width - size) + string
from revelation.utils import get_exponent, get_mantissa, bits2float
from revelation.utils import float2bits, format_thousands, is_nan, is_inf
from revelation.utils import is_zero, sext_3, sext_11, sext_24, zfill
import math



def test_format_number():
    assert '1' == format_thousands(1)
    assert '11' == format_thousands(11)
    assert '111' == format_thousands(111)
    assert '1,111' == format_thousands(1111)
    assert '11,111' == format_thousands(11111)
    assert '1,111,111' == format_thousands(1111111)
    assert '11,111,111' == format_thousands(11111111)
    assert '111,111,111' == format_thousands(111111111)
    assert '1,111,111,111' == format_thousands(1111111111)


def test_zfill():
    assert '000001' == zfill('1', 6)
    assert '+00001' == zfill('+1', 6)
    assert '-00001' == zfill('-1', 6)


def test_sign_extend_3bit():
    assert sext_3(0b011) == 0b011

    assert sext_3(0b111) == 0xffffffff