Created
October 8, 2023 16:08
-
-
Save awmc000/4591c58ac44af35fe816fa94a6beb5c0 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| # float_conversion.py | |
| import sys | |
| import random | |
| from binary_fractions import Binary | |
| options = ''' | |
| Enter an option: | |
| a........ Practice: binary16 floats --> real numbers | |
| b........ [Some issues] Practice: real numbers --> binary16 floats | |
| c........ [Not implemented] Step by Step Practice: real number -> binary16 float | |
| d........ [Not implemented] Step by Step Practice: binary16 float -> real number | |
| e........ Show the values of each bit in a binary fraction | |
| q........ Quit | |
| ''' | |
| incorrect_guess = 'Incorrect. Try again or enter \'q\' to quit.' | |
| bit_values = ''' | |
| 1/2 : 0.5 | |
| 1/4 : 0.25 | |
| 1/8 : 0.125 | |
| 1/16 : 0.0625 | |
| 1/32 : 0.03125 | |
| 1/64 : 0.015625 | |
| 1/128 : 0.0078125 | |
| 1/256 : 0.00390625 | |
| 1/512 : 0.001953125 | |
| 1/1024 : 0.0009765625 | |
| ''' | |
| def get_bin16_real_pair(): | |
| # Generate a random 16 bits | |
| bin16 = '' | |
| for i in range(16): | |
| bin16 += str(random.randint(0, 1)) | |
| # Determine exponent in decimal | |
| exp = int(bin16[1:6], 2) | |
| # Remove exponent bias | |
| exp -= 15; | |
| # Convert significand to decimal | |
| significand = 1.0 | |
| bit = 2 | |
| for digit in bin16[6::]: | |
| if digit == '1': | |
| significand += (1 / bit) | |
| bit *= 2 | |
| real = '' | |
| if bin16[0] == '1': | |
| real += '-' | |
| real += str(significand * (2 ** exp)) | |
| if len(real[real.find('.'):]) > 6: | |
| real = real[0:real.find('.') + 6] | |
| return [bin16, real] | |
| def binary16_to_real(): | |
| pair = get_bin16_real_pair() | |
| print('Convert to real up to 5 decimal places: ' + pair[0]) | |
| guess = input() | |
| while guess != pair[1] and guess != 'q': | |
| print('Incorrect. Guess again or enter q to quit.') | |
| guess = input() | |
| if guess == pair[1]: | |
| print("Correct!") | |
| print('The real number was' + pair[1]) | |
| print(options) | |
| def real_to_binary16(): | |
| pair = get_bin16_real_pair() | |
| while len(pair[1][pair[1].find('.'):]) > 6 or \ | |
| len(pair[1][:pair[1].find('.')]) > 5: | |
| pair = get_bin16_real_pair() | |
| print('Convert to a binary16 float:' + pair[1]) | |
| guess = input().replace(' ', '') | |
| while guess != pair[0] and guess != 'q': | |
| print('Incorrect. Guess again or enter q to quit.') | |
| if len(guess) != 16: | |
| print('Your guess was ' + str(len(guess)) + ' bits long. It should be 16') | |
| guess = input().replace(' ', '') | |
| if guess == pair[0]: | |
| print("Correct!") | |
| print('The binary16 float was' + pair[0]) | |
| print(options) | |
| def real_to_binary16_steps(): | |
| pair = get_bin16_real_pair() | |
| #while len(pair[1][pair[1].find('.'):]) > 6 or \ | |
| #len(pair[1][:pair[1].find('.')]) > 5: | |
| # pair = get_bin16_real_pair() | |
| print('Convert to a binary16 float:' + pair[1]) | |
| sign_bit = pair[0][0] | |
| print('Step 1: Determine sign bit. 0 if positive, 1 if negative.') | |
| sign_bit_guess = '' | |
| while sign_bit_guess != sign_bit: | |
| if sign_bit_guess == 'q': | |
| return | |
| sign_bit_guess = input("Enter the sign bit:") | |
| print('Try again.') | |
| print('Okay, we have the sign bit. Our number is now ' + sign_bit + (15 * '□')) | |
| pure_binary_abs_value = abs(float(pair[1])) | |
| print('Step 2: Convert the absolute base 10 value to pure binary.') | |
| fixed_point = str(Binary(pure_binary_abs_value))[2:] | |
| # If the fixed point value is whole, we need to add '.0' | |
| if fixed_point.find('.') == -1: | |
| fixed_point += '.0' | |
| fixed_point_guess = '' | |
| while fixed_point_guess != fixed_point: | |
| if fixed_point_guess == 'q': | |
| return | |
| fixed_point_guess = input('Enter ' + str(pure_binary_abs_value) + ' in fixed point binary:') | |
| print(incorrect_guess) | |
| print('Correct!') | |
| print('The fixed point value is ' + fixed_point) | |
| # Compute Distance between binary point and leftmost 1. | |
| leftmost_one_pos = fixed_point.find('1') | |
| binary_point_pos = fixed_point.find('.') | |
| one_point_distance = binary_point_pos - leftmost_one_pos | |
| print('distance to move binary pt: ' + str(one_point_distance)) | |
| print(options) | |
| def main() -> int: | |
| # Game loop | |
| print(options) | |
| c = input() | |
| while c != 'q': | |
| # Player chose binary16->real | |
| if c == 'a': | |
| binary16_to_real() | |
| elif c == 'b': | |
| real_to_binary16() | |
| elif c == 'c': | |
| real_to_binary16_steps() | |
| elif c == 'e': | |
| print(bit_values) | |
| # Get next choice | |
| c = input() | |
| if __name__ == '__main__': | |
| sys.exit(main()) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment