/* YOUR FILE-HEADER COMMENT HERE */ #include #include #include #include /** * Given a 16-bit binary value, break down its IEEE-754 half-precision * floating point representation. * * Display the sign bit, un-biased exponent, and significand * (including the leading implied bit). If the value is special, * display what kind of value it is. For infinity and NaN, the leading * implied bit is a don't care, and the actual magnitude is a don't * care. * * @param[in] val 16-bit floating point value to analyze. * @return true if @a val is a normal floating point value, false * otherwise */ static bool half_float_parse(uint16_t val) { _Float16 f = *((_Float16 *) & (val)); printf("For the bit pattern 0x%04x (half float value: %g):\n", val, (float)f); bool retval = false; /* PART 1: YOUR CODE HERE */ return retval; } /** * Perform 16-bit unsigned integer multiplication of @a i1 and @a i2, * returning the 32-bit product. * * SPECIAL RESTRICTION: You may only use addition, subtraction, * shifts, rotate, bitmasks, compare, and branch operations. You * may not use any built-in multiplication, division, * nor modulo division instructions for this part. * * SPECIAL RESTRICTION: If this code function is implemented using * iteration, it must complete in 16 iterations or * fewer. In other words, you may not write this * function like so: *
 *    uint32_t product = 0;
 *    while (i1 > 0) {
 *        product += i2;
 *        i1--;
 *    }
 *    return product;
 * 
* * @param[in] i1 Multiplicand * @param[in] i2 Multiplier * @return 32-bit product */ static uint32_t uint16_mult(uint16_t i1, uint16_t i2) { uint32_t product = 0; /* PART 2: YOUR CODE HERE */ return product; } /** * Given two IEEE-754 half-precision floating point normal values, * calculate their product. Assume the product will also be a normal * value. It is your responsibility to re-normalize the product. * * SPECIAL RESTRICTION: You must use your uint16_mult function when * calculating the significand. * * NOTE: Because of floating point rounding, your calculated LSB may * differ from the native C implementation by one digit. You are not * required to implement rounding. * * @param[in] val1 First 16-bit floating point value to multiply. * @param[in] val2 Second 16-bit floating point value to multiply. * @return 16-bit floating point product */ static uint16_t half_float_mult(uint16_t val1, uint16_t val2) { uint16_t retval = 0; /* PART 3: YOUR CODE HERE */ return retval; } int main(int argc, char *argv[]) { if (argc < 3) { fprintf(stderr, "Need at least two arguments\n"); exit(EXIT_FAILURE); } char *endptr; unsigned long long arg1 = strtoull(argv[1], &endptr, 0); if (!(*(argv[1])) || *endptr) { fprintf(stderr, "Argument 1 not a number: %s\n", argv[1]); exit(EXIT_FAILURE); } unsigned long long arg2 = strtoull(argv[2], &endptr, 0); if (!*(argv[2]) || *endptr) { fprintf(stderr, "Argument 2 not a number: %s\n", argv[2]); exit(EXIT_FAILURE); } uint16_t i1 = (uint16_t) arg1; uint16_t i2 = (uint16_t) arg2; bool is_arg1_normal; bool is_arg2_normal; is_arg1_normal = half_float_parse(i1); is_arg2_normal = half_float_parse(i2); uint32_t true_prod = i1 * i2; printf("Part 2: unsigned integer multiply 0x%04X and 0x%04X:\n", i1, i2); printf(" correct result: 0X%06X\n", true_prod); uint32_t your_prod = uint16_mult(i1, i2); printf(" your result: 0X%06X\n", your_prod); if (!is_arg1_normal || !is_arg2_normal) { exit(EXIT_SUCCESS); } _Float16 f1 = *((_Float16 *) & (i1)); _Float16 f2 = *((_Float16 *) & (i2)); _Float16 true_float_prod = f1 * f2; uint16_t true_float_prod_val = *((uint16_t *) &(true_float_prod)); printf("Part 3: half-float multiply %g and %g:\n", (float) f1, (float) f2); printf(" correct result: 0x%04X\n", true_float_prod_val); uint16_t your_float_prod = half_float_mult(i1, i2); printf(" your result: 0x%04X\n", your_float_prod); return 0; }