This is to be an individual effort. No partners. No Internet code/collaboration. Protect your code from anyone accessing it. Do not post code on public repositories. No late work allowed
after 48 hours; each day late automatically uses one of your tokens. Core Topics: Floating Point, Bitwise Operators, C Programming Design (Helper Functions) 1. Project Overview Micro-Ubiquitous Accounting Notary (MUAN) Programming Language is an expression-only, interpreted programming language designed to run on an embedded system without any hardware floating-point support. Many embedded systems typically do not have support for floats. You won't have to worry about any of this, of course, but it means that you won't be able to use any normal float or double variables. You may not use any C float or double types in your Solution Your job is to implement TinySF, which is a custom 12-bit floating-point library. You will be implementing functions to create the TinySF 12-bit floating point library that MUAN will be using. You will be completing six functions in src/tinysf.c for the API; however, it is highly recommended that you write many helper functions. 2. The MUAN Programming Language The MUAN programming language is already written; all you have to do is finish the API implementation for the four TinySF functions in tinysf.c that MUAN will use. MUAN is a python-like interpretive programming language that will execute expressions using basic operators, constants, and variables. Like python, you can also write programs (eg. scripts) that you can run and see the output of. Your TinySF code is a library that adds the ability to work with Floating Point values to the MUAN programming language. Since MUAN is designed for embedded hardware, there are no float or double data types available natively. Your library adds floating-point support to MUAN programs. Please refer to the MUAN Manual document for information on how to program using MUAN. This manual also has a large amount of sample inputs and output values. 3. Specification for Project 2 We've already written the MUAN Programming language for you and provided you with the stubs (empty functions) for the six functions you will be writing inside of src/tinysf.c Complete this code, along with any number of helper functions that you would like to use, to implement these six functions. In this project, you will be working with our custom tinysf_s type variables. These custom types are 32-bit unsigned ints in memory. Within these 32-bits, you will be encoding our custom 12-bit floating point value. Since a tinysf_s type is just a standard unsigned int, you can do operations on it just like you normally would with an unsigned int. (eg. shifting, masking, and other bitwise ops). Ultimately, you will be getting the S, exp, and frac information and storing them within your tinysf_s value, just like we've been doing in class. TinySF Representation (tinysf_s) Values The tinysf_s values are encoded using the following format within an unsigned 32-bit int. Normalized and Special Encoding Format: S Unused Bits (MUST BE OS) 00000000000000000000 S This is the 12-bit Representation for tinysf_s values: 1 bit for sign (s), 4 bits for exponent (exp) and 7 bits for fraction (frac) TinySF is a slightly simplified version of floating-point encoding. We can support Negative, Normalized, Round-to-Nearest/Even, and Special (NaN or ∞o) encodings as discussed in class. exp frac e e eeff f f f f f MUAN does not do Denormalized. Any underflows (too small for Normalized) will be encoded as the special Zero Value, which is all Os in the exp and frac. Sign could be 1 or 0, however. The Zero Value: Unused Bits (MUST BE Os) S exp frac 0000000000000000000000000000000 When exp is all zeroes, frac should also be all zeroes. Any other frac value would be invalid. If any function receives a tinysf_s with the upper bits set to anything except all Os, you must safely ignore them. We will only test with values that have upper bits set to Os, as is specified. Input Values to TinySF Since this is a program for a computer that does not have formal floating-point support, you may notice that there are no float or double types anywhere in the code for this program. In fact, you will not be allowed to use any float or double types in your solution either. Because of this, the inputs to the functions you will be writing will be int types inside of a struct. These values will give you all the information that you need to use to implement your custom floating-point type (tinysf_s) values. Number Struct Definition (inc/common_structs.h): typedef struct number_struct { int is negative; int is_infinity; int is nan; unsigned int whole; (eg. For 3.25, whole = 0x3) unsigned int fraction; // 32-bit Fraction Portion in Binary // (eg. For 3.25, frac =0x40000000, which represents .01000000000000...) Factoring_s conversion; // Used Internally by MUAN, Ignore this! } Number_s; // 1 if Negative, 0 if Positive // 1 if Infinity, 0 Otherwise // 1 if NaN, 0 Otherwise // 32-bit Whole Portion of Number in Binary Two of your functions (toTinySF and toNumber) will have this struct passed into them by reference. Do NOT free those when you are done with them. (They are controlled by MUAN). Example: Let's say someone enters the value 3.0625 in MUAN. MUAN will pass a Number_s struct to your toTinySF function with the following members set: is_negative = 0 is_infinity = 0 is_nan = 0 whole = 3 fraction = 0x10000000 (in GDB, you can print in hex with print/x instead of print) o 3.0625 is 11.000100 in Binary. The fraction field is a 32-bit unsigned int that has the Binary value of the fraction. So, .0001 would be .0001 0000 0000 0000 0000 0000 0000 0000 as 32-bit value. fraction gives you the bits to the right of the binary point, as a 32-bit value. 0001 0000 0000 0000 0000 0000 0000 0000, which is Ox10000000 o So, fraction gives you the fraction component AS a whole 32-bit value. ● ● Binary Scientific Notation In the previous example, we have 3.0625 entered, which gave us the following in number: whole = 0x3 [Representing 0000 0000 0000 0000 0000 0000 0000 0011] [Representing 0001 0000 0000 0000 0000 0000 0000 0000] fraction = 0x10000000 Together, these represent 11.000100, whose value is 3.065, but we don't have a leading 1 to start working with this as Normalized. To fix this, do the same technique we show in class by shifting the bits of the Mantissa. 11.0001000... The Whole number part is > 1 Shift to the Right Once 01.1000100... The Whole number is in range. ננננננננ whole 0x1 frac = 0x88000000 How can we do that in code? Remember each part is represented by an unsigned int. Think about using shifting and bitwise operations to shift both parts (whole and fraction) left or right. Infinity Values and Overflows on Input into MUAN The number struct will give you three ints to tell you if the user entered negative or special values. Note, this is only for special values typed by the user in MUAN. So, if a user enters the following: ¯\__()_/¯ $ a = inf MUAN will call your to TinySF function with the number struct that has is_infinity = 1 set. However, you can still end up with infinity through an overflow. So, with the following: "¯\_()_/¯ $a = 300 MUAN will call your toTinySF function with the number struct that has is_infinity = 0, because the user did not enter inf, however, that number will still end up overflowing to infinity, so you will end up returning the infinity floating point encoding. (Note: 256.0 is an overflow in TinySF) Entering Negative Values Pay special attention to the is_negative flag and make sure to set your S bit accordingly. "\_()_/¯ $ value = -2.0 MUAN will pass you a Number struct that has is_negative = 1 because the user entered a negative value. Always check is_negative in toTinySF, so you know what to set your S it to in the value. 4. Function Descriptions src/tinysf.c has been given to you as your starting file. This contains a stub for all six required functions. You are strongly encouraged to create helper functions, constants, etc. in your design. They too must all be kept within tinysf.c as this is the only file you will be submitting. If any function receives a tinysf_s with the upper bits set to anything except all Ös, you must safely ignore them. We will only test with values that have upper bits set to Os, as is specified. You are not allowed to use any float or double types in this project. Write the code for these functions, using bitwise operators for encoding/decoding. TinySF Function: tinysf s toTinySF (Number_s *number) When MUAN gets any number, (example: apple -1.25) it will call this function. toTinySF will take a Number Struct (with its whole and fraction parts) and encode the data into our custom 12-bit representation and return that value. = tinysf_s is a typedef for an unsigned 32-bit int in C Once you have encoded the value into this tinysf_s, you will be returning it. Example: The val -1.25 has Sign = 1, exp = 0111, frac = 0100000 The 12-bit encodings should be: 1 0111 0100000 The full tinysf_s (32-bit) value will be: 0000 0000 0000 0000 0000 1011 1010 0000 Hex: 0xBAO (You can confirm this with ref_all_values) So, how do you get these fields from the value? You are not allowed to use float or double when working within your function, but you can do the same operations we did in class. (Hint: Think of Binary Scientific Notation) Think carefully in your design about how you want to shift the whole and fraction integers, and how you will need to move values between them, to get the right format for Binary Scientific Notation. Remember also that you will need to have something to track your E component and that for each shift you do, you will need to adjust that E. The key idea is to get your value into the right range while adjusting E. This will give you the ability to determine the S, E, and M components first.