Last active
March 31, 2020 15:19
-
-
Save tiagox/58019bc11490ec31fb9105dd505a1da9 to your computer and use it in GitHub Desktop.
This file contains 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
{ | |
"cells": [ | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"# Decimal to Binary Machine Number" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 1, | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"from math import modf\n", | |
"\n", | |
"def estimate_machine_number(x):\n", | |
" \"\"\"Return a tuple with the binary representation of the parts of a machine number.\n", | |
" \n", | |
" Parameters\n", | |
" ----------\n", | |
" x :\n", | |
" the number to be estimated to machine number.\n", | |
"\n", | |
" Return\n", | |
" ------\n", | |
" tuple\n", | |
" (<sign:1 bit>, <exp sign:1 bit>, <exp:7 bits>, <mantissa:23 bits>)\n", | |
" \"\"\"\n", | |
" # Sign of the number 0 if positive, 1 is negative\n", | |
" sign = 0 if x > 0 else 1\n", | |
" (decimal, integer) = modf(abs(x))\n", | |
" \n", | |
" # Calculate the integer part of the number\n", | |
" integer = int(integer)\n", | |
" integer_part = '{:b}'.format(integer) if integer > 0 else ''\n", | |
" integer_places = len(integer_part)\n", | |
" \n", | |
" # Calculate the decimal part of the number\n", | |
" decimal_part = ''\n", | |
" while decimal > 0:\n", | |
" (decimal, integer) = modf(decimal * 2)\n", | |
" decimal_part += str(int(integer))\n", | |
" \n", | |
" # The mantissa will be the conjuntion of integer and decimal parts\n", | |
" mantissa = integer_part + decimal_part\n", | |
" \n", | |
" # Calculate the exp of the machine number\n", | |
" exp = 0\n", | |
" if integer_places > 0:\n", | |
" exp = integer_places\n", | |
" else:\n", | |
" while mantissa[0] == '0':\n", | |
" mantissa = mantissa[1:]\n", | |
" exp -= 1\n", | |
" \n", | |
" # Sign of the exp 0 if positive, 1 is negative\n", | |
" exp_sign = 0 if exp > 0 else 1\n", | |
" exp = abs(exp)\n", | |
" \n", | |
" # If the mantissa is longer than 24 digits, we need to approximate it\n", | |
" if len(mantissa) > 24:\n", | |
" # x_1 will be the floor of the first 24 digits.\n", | |
" x_1 = mantissa[0:24]\n", | |
" # x_2 will be the ceil of the first 24 digits, so x_1 + 2^{-24}\n", | |
" x_2 = '{:b}'.format(int(x_1, 2) + 1)\n", | |
" # From normalize notation we'll move the decimal point 26 places, \n", | |
" # so we could calculate the distance between the mantissa, x_1 & x_2\n", | |
" ref_mantissa = int((mantissa + '00')[0:26], 2)\n", | |
" ref_x_1 = int(x_1 + '00', 2)\n", | |
" ref_x_2 = int(x_2 + '00', 2)\n", | |
" # We select the closer number to the original mantissa\n", | |
" mantissa = x_1 if (ref_mantissa - ref_x_1) <= (ref_x_2 - ref_mantissa) else x_2\n", | |
" \n", | |
" sign = '{:01b}'.format(sign) # Format sign in binary\n", | |
" exp_sign = '{:01b}'.format(exp_sign) # Format exp sign in binary\n", | |
" exp = '{:07b}'.format(exp) # Format the exp in binary\n", | |
" mantissa = (mantissa + ('0' * 24))[1:24] # Return a 23 bits binary number\n", | |
"\n", | |
" return (sign, exp_sign, exp, mantissa)" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 2, | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"data": { | |
"text/plain": [ | |
"('0', '1', '0000011', '10011001100110011001101')" | |
] | |
}, | |
"execution_count": 2, | |
"metadata": {}, | |
"output_type": "execute_result" | |
} | |
], | |
"source": [ | |
"estimate_machine_number(1/10)" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 3, | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"data": { | |
"text/plain": [ | |
"('0', '1', '0000000', '10011001100110011001101')" | |
] | |
}, | |
"execution_count": 3, | |
"metadata": {}, | |
"output_type": "execute_result" | |
} | |
], | |
"source": [ | |
"estimate_machine_number(4/5)" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 4, | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"data": { | |
"text/plain": [ | |
"('0', '1', '0000010', '00000000000000000000000')" | |
] | |
}, | |
"execution_count": 4, | |
"metadata": {}, | |
"output_type": "execute_result" | |
} | |
], | |
"source": [ | |
"estimate_machine_number(0.125)" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 5, | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"data": { | |
"text/plain": [ | |
"('0', '0', '0000111', '10010000000000000000000')" | |
] | |
}, | |
"execution_count": 5, | |
"metadata": {}, | |
"output_type": "execute_result" | |
} | |
], | |
"source": [ | |
"estimate_machine_number(100)" | |
] | |
} | |
], | |
"metadata": { | |
"kernelspec": { | |
"display_name": "Python 3", | |
"language": "python", | |
"name": "python3" | |
}, | |
"language_info": { | |
"codemirror_mode": { | |
"name": "ipython", | |
"version": 3 | |
}, | |
"file_extension": ".py", | |
"mimetype": "text/x-python", | |
"name": "python", | |
"nbconvert_exporter": "python", | |
"pygments_lexer": "ipython3", | |
"version": "3.7.6" | |
} | |
}, | |
"nbformat": 4, | |
"nbformat_minor": 2 | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment