The object of this assignment is to familiarize yourself with modules, bit-manipulations. #ifdefs, and more pointers. (There are still no donuts to be counted for this assignment) The assignment is due March 3rd at 11:59 pm (before midnight). The assignment will be turned in electronically via the turnin command. The name for the assignment is 352assign3, so when you are ready to submit your solutions, you'll need to do: turnin 352assign3 main.c extract.c extract.h sizes.h where main.c contains the "main()" routine (C source code), and extract.h and extract.c contain the C source code for a bit extraction module for your assignment. The sizes.h file contains the typedefs for integers of the proper size. YOU MUST DECOMPOSE YOUR PROGRAM INTO THE FILES AS DESCRIBED ABOVE OR YOU WILL LOSE CONSIDERABLE POINTS. When you are providing code for other people, you need to make sure the APIs and structure are as expected. Scenario: You are helping write code for the next versions of the iPhone: the mePhone and the myselfPhone. They will both be using the ARM processor, which has no floating point hardware built-in. Thus all floating point additions and subtractions, etc. have to be emulated in software. You are going to write code to help with this task. The actual hardware isn't available just yet, but that's okay because C is portable assembly. You can write the C code and it should work assuming you can find similar hardware. The mePhone is a 32-bit processor and the myselfPhone is a 64-bit processor. For the purposes of this assignment, you will use "lectura" as your 64-bit machine and one of the 8 Linux machines downstairs (fd01-fd08 or angora, koran, manx, mau, rex, ocicat, sphynx, somali) in the Gould-Simpson 228 lab as the 32-bit machines. When we go to test and run your programs, we will be using lectura as the 64-bit machine and one of the GS-228 machines as the 32-bit machines. Another group will be providing the majority of the floating point add code, you just need to provide some routines to help them out. You need to write an extract module. /* extract module: code to help manipulate and debug floating point */ #include "sizes.h" /* User-defined defns for int_u8, int_8, int_u4, int_4 */ /* Extract the sign, mantissa and exponent from the given IEEE floating ** number. The mantissa returned should have the hidden bit in the ** value, and the exponent should have the excess-127 already taken ** out. The sign should just be -1 or 1. In case the number is 0, ** the sign, mantisaa ad exponent should all be 0. We will not ** handle denormalized numbers, infinities, just basic numbers ** that can be represented in IEEE floating point numbers. */ void getSignMantissaExponent(float number, int_4* sign, int_u8* mantissa, int_4* exponent); /* Given the sign, mantissa and exponent, print out the floating point ** number in binary: it should show the hidden bit. The mantissa ** is printed in binary and the exponent is printed as a decimal ** number. For example: ** 10 -> +1.01000000000000000000000e+3 ** -10 -> -1.01000000000000000000000e+3 ** .5 -> +1.00000000000000000000000e-1 ** 0 -> 0.00000000000000000000000e+0 ** Note that '0' prints a space out instead of + or - for the sign */ void binaryFloatPrint(int_4 sign, int_u8 mantissa, int_4 exponent); You will need to provide the extract.h file: it should look a LOT like what we have above, with a few more things. You will also write an extract.c file for this module. Thus, when someone wants to use your bit-extraction module, they use #include "extract.h" Inside their code. Then, to link with it, they'll have to add extract.c to their compile line (as well as a few other things which we'll explain later below). % gcc -DMACHINE64 -ansi -Wall extract.c sometest.c -o sometest You will also provide a driver program (main.c) to demonstrate that your module is working. We will run and test this module to make sure you think your code works, but we will also be writing our main routines to test out your module, like the sometest above. The main.c you provide should be able to handle command-line arguments. It requires at least 1 argument, the floating point number to extract the sign, mantssa and exponent from. The output (like below) should go to standard output. % gcc -DMACHINE64 -ansi -Wall extract.c main.c -o main % ./main 100.0 100.000000 has sign bit:1 mantissa:0xc80000 exponent:6 % echo $status 0 A few things to note from the example above: First, when the program succeeds (i.e., it extracts bits correctly like above), it should return 0 to indicate that (which is why $status is 0). Second, note that the mantissa is printed out in hexadecimal, and the exponent is printed in decimal. Here are a few more examples: % ./main .5 0.500000 has sign bit:1 mantissa:0x800000 exponent:-1 % ./main 0 0.000000 has sign bit:0 mantissa:0x0 exponent:0 % ./main -10 -10.000000 has sign bit:-1 mantissa:0xa00000 exponent:3 If you forget to give an argument, it should output a usage message to standard error like the following (and exit with a non-zero value so we know the UNIX program failed): This is how most UNIX command-line programs behave. % ./main usage: ./main [--binary] floatnumber % echo $status 1 Printing out the mantissa in binary is a useful debugging feature that your main.c should support. Of course, the code to print binary floats should be compiled in from your extract module. % ./main --binary 10 10.000000 in binary:+1.01000000000000000000000e+3 % ./main --binary -10 -10.000000 in binary:-1.01000000000000000000000e+3 % ./main --binary .5 0.500000 in binary:+1.00000000000000000000000e-1 The same program and the same code needs to run on multiple platforms: the 32-bit mePhone and the 64-bit myselfPhone. When we compile any "test" program with the extract.{h.c} module, we need to provide a #define __from the command-line__ to indicate which platform we are using. For 32-bit machines, we use: -DMACHINE32 For 64-bit machines, we use: -DMACHINE64 If you forget to compile with these qualifiers on the command-line, you should a compile-time error (from the #error), something like: % gcc -ansi -Wall extract.c main.c -o main # FORGOT -DMACHINE64 !!! In file included from extract.h:4, from main.c:5: sizes.h:21:2: error: #error 666 In file included from main.c:5: extract.h:15: error: expected declaration specifiers or b..b If you supply the wrong MACHINE type, the program should compile, but your main.c program should have a run-time test (the first thing it does before anything else) making sure that the sizes are correct. For example, if you try using MACHINE32 on lectura: % gcc -ansi -Wall -DMACHINE32 extact.c main.c -o main % ./main 10 ERROR: sizeof(int_u4) is not 4, it's 8 ERROR: sizeof(int_4) is not 4, it's 8 aborting % echo $status # program failed 1 Similarly, on a 32-bit machine: % gcc -DMACHINE64 -ansi -Wall main.c extract.c -o main % ./main ERROR: sizeof(int_u8) is not 8, it's 4 ERROR: sizeof(int_8) is not 8, it's 4 aborting % echo $status # program failed 1 Your main.c that you turn in will be checked to make sure it can handle the cases we described above (a run-time check to make sure the sizes of the typedefs int_4, int_u4, int_8 and int_u8 are all correct). Test-cases will be available in ~cs352/spring08/assign3. You can sure we will be looking for (1) Forgetting the -DMACHINE32 or -DMACHINE64 (compile-time failure) (2) Using the wrong #define (run-time failure) (3) Extracting from 0 (4) Extracting from negative numbers (5) Extracting from positive numbers (6) Extracting from negative exonents (7) Making sure your routines compile with OUR test cases. (8) Making sure both 32-bit and 64-bit versions actually work (repeating the same test cases on the 32-bit machines and 64-bit machines).