Esempio n. 1
0
def test_fp_frac_width_overflow():
    with pytest.raises(InvalidNumericType, match=r"overflow"):
        FixedPoint("0.25", 2, 1, False)
    with pytest.raises(InvalidNumericType, match=r"overflow"):
        FixedPoint("0b111", 2, 1, True)
    with pytest.raises(InvalidNumericType, match=r"overflow"):
        FixedPoint("0x7", 2, 1, False)
Esempio n. 2
0
 def fp_round_trip(bit_string: str) -> FixedPoint:
     # Round-trips the fixed point conversion.
     bin = FixedPoint(f"0b{bit_string}", width, int_width,
                      is_signed).str_value()
     hex = FixedPoint(f"0x{hex_string}", width, int_width,
                      is_signed).str_value()
     assert bin == hex
     return FixedPoint(
         bin,
         width,
         int_width,
         is_signed,
     )
Esempio n. 3
0
        def convert(x):

            if not is_fp:
                return Bitnum(x, **shape[k]).base_64_encode()

            try:
                return FixedPoint(x, **shape[k]).base_64_encode()
            except InvalidNumericType as error:
                if round_float_to_fixed:
                    # Only round if it is not already representable.
                    fractional_width = width - int_width
                    x = float_to_fixed(float(x), fractional_width)
                    x = str(x)
                    return FixedPoint(x, **shape[k]).base_64_encode()
                else:
                    raise error
Esempio n. 4
0
    def parse_entry(target, format_details):
        numeric_type, is_signed, (width, int_width, frac_width) = (
            format_details
            if format_details is not None
            else ("bitnum", False, (None, None, None))
        )

        if isinstance(target, list):
            return [
                parse_entry(
                    x, (numeric_type, is_signed, (width, int_width, frac_width))
                )
                for x in target
            ]
        elif isinstance(target, str):
            num = base64.standard_b64decode(target)
            int_rep = int.from_bytes(num, "little", signed=is_signed)

            if int_rep > 0 and (int_rep & (1 << (width - 1))) and is_signed:
                int_rep = -(2 ** (width - 1)) + (int_rep ^ (1 << (width - 1)))

            if numeric_type == "bitnum":
                return int_rep
            elif numeric_type == "fixed_point":
                bin_str = bin(int.from_bytes(num, "little", signed=False))
                bin_len = len(bin_str[2:])
                if bin_len < width:
                    bin_str = "0b" + ("0" * (width - bin_len)) + bin_str[2:]

                assert len(bin_str) == width + 2

                fp = FixedPoint(
                    bin_str,
                    width,
                    int_width,
                    is_signed,
                )
                return fp.str_value()
            else:
                return False, f"got {numeric_type}"
Esempio n. 5
0
def exp(x: str,
        width: int,
        int_width: int,
        is_signed: bool,
        print_results=False):
    """
    Computes an approximation of e^x.
    This is done by splitting the fixed point number
    x into its integral bits `i` and fractional bits `f`,
    and computing e^(i + f) = e^i * e^f.
    For the fractional portion, a chebyshev
    approximation is used.

    Example:
        exp(
            x="1.0",
            width=32,
            int_width=16,
            is_signed=True,
            print_results=True
        ) # Should return an approximation of e^(1.0)
    """
    frac_width = width - int_width
    bin_string = FixedPoint(x, width, int_width,
                            is_signed=False).bit_string(with_prefix=False)

    int_b = bin_string[:int_width]
    int_bin = int(int_b, 2)
    frac_b = bin_string[int_width:width]
    frac_bin = int(frac_b, 2)

    # Split e^x into e^i * e^f.
    e_i = Decimal("2.71828")**int_bin

    e_table = compute_exp_frac_table(frac_width)
    e_f = e_table[frac_bin]

    # Compute e^i * e^f.
    actual = Decimal(e_i) * Decimal(e_f)

    if print_results:
        accepted = Decimal("2.71828")**Decimal(x)
        print(f"e^{x}: {accepted}, actual: {actual}"
              f"relative difference: {(actual - accepted) / actual * 100} %")

    return actual
Esempio n. 6
0
def test_fp_int_width_overflow():
    with pytest.raises(InvalidNumericType, match=r"overflow"):
        FixedPoint("2.0", 2, 1, False)
    with pytest.raises(InvalidNumericType, match=r"overflow"):
        FixedPoint("0b101", 2, 1, True)
Esempio n. 7
0
def test_non_string_initialization():
    with pytest.raises(InvalidNumericType, match=r"string"):
        Bitnum(16, 5, False)
    with pytest.raises(InvalidNumericType, match=r"string"):
        FixedPoint(0.5, 2, 1, False)
Esempio n. 8
0
def test_empty_string():
    with pytest.raises(InvalidNumericType, match=r"non-empty string"):
        Bitnum("", 2, False)
    with pytest.raises(InvalidNumericType, match=r"non-empty string"):
        FixedPoint("", 2, 1, False)
Esempio n. 9
0
def test_unsigned_negative_number():
    with pytest.raises(InvalidNumericType, match=r"negative value"):
        FixedPoint("-0.5", 2, 1, False)
    with pytest.raises(InvalidNumericType, match=r"negative value"):
        Bitnum("-1", 2, False)
Esempio n. 10
0
def test_fp_invalid_representation():
    with pytest.raises(InvalidNumericType, match=r"not representable"):
        FixedPoint("0.1", 2, 1, False)