You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

59 lines
1.4 KiB

  1. import argparse
  2. def convert_to(dec_str: str) -> None:
  3. str_parts = dec_str.split(".")
  4. assert len(str_parts) == 2
  5. whole_str, part_str = str_parts
  6. whole_dec = int(whole_str)
  7. part_dec = float(f"0.{part_str}")
  8. part_bits = []
  9. for i in range(1, 9, 1):
  10. bit = "0"
  11. sub = 1 / (1 << i)
  12. if part_dec > sub:
  13. bit = "1"
  14. part_dec = part_dec - sub
  15. part_bits.append(bit)
  16. part_dec = int("".join(part_bits), 2)
  17. assert whole_dec <= 0xFF
  18. assert part_dec <= 0xFF
  19. print(f"0x{bytes([whole_dec, part_dec]).hex()}")
  20. def convert_from(hex_str: str) -> None:
  21. assert hex_str.startswith("0x")
  22. assert len(hex_str) == 6
  23. whole_bin = int(hex_str[2:4], 16)
  24. # TODO: support negatives
  25. # if whole_bin & (1 << 7):
  26. # whole_bin = -
  27. part_bin = int(hex_str[4:6], 16)
  28. part_dec = 0
  29. for i in range(1, 9, 1):
  30. mask = 1 << (8 - i)
  31. if part_bin & mask:
  32. part_dec += 1 / (1 << i)
  33. print(f"{whole_bin + part_dec}")
  34. def main() -> None:
  35. parser = argparse.ArgumentParser("convert_fixed_point")
  36. parser.add_argument("-d", "--decode", action="store_true")
  37. parser.add_argument("decimal")
  38. args = parser.parse_args()
  39. if args.decode:
  40. convert_from(args.decimal)
  41. else:
  42. convert_to(args.decimal)
  43. if __name__ == "__main__":
  44. main()