import argparse def convert_to(dec_str: str) -> None: str_parts = dec_str.split(".") assert len(str_parts) == 2 whole_str, part_str = str_parts whole_dec = int(whole_str) part_dec = float(f"0.{part_str}") part_bits = [] for i in range(1, 9, 1): bit = "0" sub = 1 / (1 << i) if part_dec > sub: bit = "1" part_dec = part_dec - sub part_bits.append(bit) part_dec = int("".join(part_bits), 2) assert whole_dec <= 0xFF assert part_dec <= 0xFF print(f"0x{bytes([whole_dec, part_dec]).hex()}") def convert_from(hex_str: str) -> None: assert hex_str.startswith("0x") assert len(hex_str) == 6 whole_bin = int(hex_str[2:4], 16) # TODO: support negatives # if whole_bin & (1 << 7): # whole_bin = - part_bin = int(hex_str[4:6], 16) part_dec = 0 for i in range(1, 9, 1): mask = 1 << (8 - i) if part_bin & mask: part_dec += 1 / (1 << i) print(f"{whole_bin + part_dec}") def main() -> None: parser = argparse.ArgumentParser("convert_fixed_point") parser.add_argument("-d", "--decode", action="store_true") parser.add_argument("decimal") args = parser.parse_args() if args.decode: convert_from(args.decimal) else: convert_to(args.decimal) if __name__ == "__main__": main()