src/ 0000755 0003303 0003022 00000000000 13042745060 011352 5 ustar fsieker others src/iFloat.c 0000600 0003303 0003022 00000003455 13042711162 012727 0 ustar fsieker others #include "Debug.h" #include "iFloat.h" /** @file iFloat.c * @brief You will modify this file and implement nine functions * @details Your implementation of the functions defined in iFloat.h. * You may add other function if you find it helpful. Added function * should be declared static to indicate they are only used * within this file. *
* @author Your name goes here
*/
/* declaration for useful function contained in testFloat.c */
const char* getBinary (iFloat_t value);
/** @todo Implement in based on documentation contained in iFloat.h */
iFloat_t floatGetSign (iFloat_t x) {
return 0; /* implement this */
}
/** @todo Implement in based on documentation contained in iFloat.h */
iFloat_t floatGetExp (iFloat_t x) {
return 0; /* implement this */
}
/** @todo Implement in based on documentation contained in iFloat.h */
iFloat_t floatGetVal (iFloat_t x) {
return 0;
}
/** @todo Implement in based on documentation contained in iFloat.h */
void floatGetAll(iFloat_t x, iFloat_t* sign, iFloat_t*exp, iFloat_t* val) {
}
/** @todo Implement in based on documentation contained in iFloat.h */
iFloat_t floatLeftMost1 (iFloat_t bits) {
return -1;
}
/** @todo Implement in based on documentation contained in iFloat.h */
iFloat_t floatAbs (iFloat_t x) {
return 0;
}
/** @todo Implement in based on documentation contained in iFloat.h */
iFloat_t floatNegate (iFloat_t x) {
return 0;
}
/** @todo Implement in based on documentation contained in iFloat.h */
iFloat_t floatAdd (iFloat_t x, iFloat_t y) {
debug("%s: bits of x (IEEE 754)", getBinary(x)); // example only
debug("%s: bits of y (IEEE 754)", getBinary(y)); // example only
return 0;
}
/** @todo Implement in based on documentation contained in iFloat.h */
iFloat_t floatSub (iFloat_t x, iFloat_t y) {
return 0;
}
src/convert.h 0000444 0003303 0003022 00000001636 13042735156 013214 0 ustar fsieker others #ifndef __CONVERT_H__
#define __CONVERT_H__
#include "iFloat.h"
/** @file convert.h
* @brief Defines interface of convert.c functions (do not modify)
* @details This file defines the interface to a C file convert.c that
* converts between
* A sample execution might be:
* which prints
* To use the
* which prints
* This is the decimal, hex and binary representation of the floating point
* number 1.5. You will find the
* @author Fritz Sieker
*/
/** Get the binary representation of a value starting at the specified
* bit position. A separator is printed every 4 bits for easy reading.
* This function return a pointer to a static buffer, so that the result
* must be used, before it is called again. In particular, you may NOT
* have multiple calls to this function in a single DEBUG() call.
* @param value the value to be converted to binary
* @param msb the bit position to begin printing (31 to 0)
* @return a string of bits with a separator every four characters
*/
const char* getBinaryMSB (int value, int msb) {
static char bits[48];
int i = 0;
while (msb >= 0) {
bits[i++] = ((value & (1 << msb)) ? '1' : '0');
if (msb && ((msb & 0x3) == 0))
bits[i++] = '-';
msb--;
}
bits[i] = '\0'; // terminate string
return bits;
}
/** Get a 16/32 bit binary representation of a value.
* @param value the value to be converted to binary
* @return a string of bits with a separator every four characters
*/
const char* getBinary (iFloat_t value) {
return getBinaryMSB(value, BITS-1);
}
/** Print a usage statement, then exit the program returning a non zero
* value, the Linux convention indicating an error
*/
static void usage() {
puts("usage: testFloat [-debug] abs FPvalue");
puts(" testFloat [-debug] all FPvalue");
puts(" testFloat [-debug] add FPvalue1 FPvalue2");
puts(" testFloat [-debug] bin FPvalue");
puts(" testFloat [-debug] exp FPvalue");
puts(" testFloat [-debug] lm1 Intvalue");
puts(" testFloat [-debug] neg FPvalue");
puts(" testFloat [-debug] sign FPvalue");
puts(" testFloat [-debug] sub FPvalue1 FPvalue2");
puts(" testFloat [-debug] val FPvalue\n");
exit(1);
}
/** Entry point of the program
* @param argc count of arguments, will always be at least 1
* @param argv array of parameters to program argv[0] is the name of
* the program, so additional parameters will begin at index 1.
* @return 0 the Linux convention for success.
*/
int main (int argc, const char* argv[]) {
iFloat_t x, y;
debugInit(&argc, argv);
if (argc < 3) {
usage();
}
const char* op = argv[1];
x = toiFloat(argv[2]);
if (argc > 3)
y = toiFloat(argv[3]);
if ((strcmp(op, "abs") == 0) && (argc == 3)) {
printf("abs(%s) --> %f\n", argv[2], fromiFloat(floatAbs(x)));
}
else if ((strcmp(op, "all") == 0) && (argc == 3)) {
iFloat_t sign, exp, val;
floatGetAll(x, &sign, &exp, &val);
printf("sign: %u exp: %u val: %s\n", sign, exp, getBinaryMSB(x, BITS_MANT));
}
else if ((strcmp(op, "add") == 0) && (argc == 4)) {
printf("%s + %s --> %f\n", argv[2], argv[3], fromiFloat(floatAdd(x, y)));
}
else if ((strcmp(op, "bin") == 0) && (argc == 3)) {
printf("dec: %u hex: 0x%X bin: %s\n", x, x, getBinary(x));
}
else if ((strcmp(op, "exp") == 0) && (argc == 3)) {
printf("exp %s --> %u\n", argv[2], floatGetExp(x));
}
else if ((strcmp(op, "lm1") == 0) && (argc == 3)) {
printf("%u\n", floatLeftMost1(x));
}
else if ((strcmp(op, "neg") == 0) && (argc == 3)) {
printf("neg(%s) --> %f\n", argv[2], fromiFloat(floatNegate(x)));
}
else if ((strcmp(op, "sign") == 0) && (argc == 3)) {
printf("sign(%s) --> %u\n", argv[2], floatGetSign(x));
}
else if ((strcmp(op, "sub") == 0) && (argc == 4)) {
printf("%s - %s --> %f\n", argv[2], argv[3], fromiFloat(floatSub(x, y)));
}
else if ((strcmp(op, "val") == 0) && (argc == 3)) {
printf("val(%s) --> %s\n", argv[2],
getBinaryMSB(floatGetVal(x), BITS_MANT));
}
else
usage();
return 0;
}
src/convert.a 0000444 0003303 0003022 00000010330 13042742263 013171 0 ustar fsieker others !float
and iFloat_t
types.
* Thus, you do not need to declare ANY float
variables
* anywhere in your code. Note that the test driver testFloat.c
* does not use any float
variables.
*/
/** Convert a string to a iFloat_t
* @param str the string to convert
* @return an iFloat_t containing the IEEE floating point value
*/
iFloat_t toiFloat (const char* str);
/** Convert a iFloat_t
to a float
* @param x the iFloat_t containing bits for a IEEE floating point value
* @return the value as a float
*/
float fromiFloat (iFloat_t x);
#endif
src/testFloat.c 0000444 0003303 0003022 00000016334 13042737442 013475 0 ustar fsieker others /*
* testFloat.c - simple driver to test methods of iFloat.h.
*
* "Copyright (c) 2012-2017 by Fritz Sieker."
*
* Permission to use, copy, modify, and distribute this software and its
* documentation for any purpose, without fee, and without written
* agreement is hereby granted, provided that the above copyright notice
* and the following two paragraphs appear in all copies of this software.
*
* IN NO EVENT SHALL THE AUTHOR BE LIABLE TO ANY PARTY FOR DIRECT,
* INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
* OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE AUTHOR
* HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* THE AUTHOR SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS"
* BASIS, AND THE AUTHOR NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT,
* UPDATES, ENHANCEMENTS, OR MODIFICATIONS."
*/
#include testFloat
in a terminal window. This will print a usage
* statement defining how to run the program. The first "logical" parameter of
* the program is always a key defining which function to run. It may be
* optionally preceeded by -debug
to turn on debugging. The
* options are:
*
*
* testFloat abs -2.5
*
* abs(-2.5) --> 2.500000
bin
option do testFloat bin 1.5
*
* dec: 1069547520 hex: 0x3FC00000 bin: 0011-1111-1100-0000-0000-0000-0000-0000
bin
option very useful as you
* can determine what the correct representation of the answer should be. To
* test you program, choose values where the correct answer is easy to compute
* in your head. Then use the bin
option to determine what the
* answer looks like. Finally, run your program and if your answer differs
* from the answer you computed, use the bin
option to see the
* pattern of your answer. Then you need to read your program, perhaps add
* debugging output (using the debug()
function), and determine
* what your program is actually doing.
*