Programming Using C Homewk 4 1. In Homewk 3 you computed the histogram of an array, in which each entry represents one value of the array. We can generalize the histogram so that each entry, called a bin, represents a range of values in the initial array. Write a program that computes a histogram with a specified number of bins. Assume that the array holds one of N=20 possible values, from 0 to N-1, and that N is a multiple of the number of bins. Your program should use this function: void histogram(int a[], int n, int h[], int n_bins); Example: Enter length: 10 Enter values: 2 1 2 0 2 3 1 0 11 0 Enter number of bins: 4 Histogram: 0... 9 1... 0 2... 1 3... 0 2. In this program you will simulate floating point additions as they are perfmed in the arithmetic-logic unit of the process. Internally in a computer floating point numbers are sted using 32 bits. One bit, the leftmost, is used to represent the sign of the number: 0 f apositive number and 1 f a negative number. The remaining 31 bits are divided into the exponent (8 bits) and mantissa (23 bits). Conversion of an integer number into binary is done through repeated integer division by 2. Each time you save the remainder and concatenate it to the left of all other remainders you have previously found. F example, the decimal number 100 converted to binary is 1100100. This is a positive number so the sign bit will be 0. The mantissa is considered to be in scientific notation, so that a decimal point is imagined to the right of the leftmost 1 of the result. The exponent is 6 because the (imagined) decimal point has to slide 6 places to the left. The mantissa will start with 1100100 and will be followed by extra zeros to fill all of the 23 bits. The result is the following 32 bits: 1
0 00000110 11001000000000000000000 00000011011001000000000000000000 The exponent is an integer value so it is right justified in its space (extra zeros are added to the left to fil all 8 digits), while the mantissa is a fraction (real number) so it is left justified. Converting this binary number back into a decimal number involves reversing the steps we just did: convert the exponent into a decimal number (110 2 = 6), slide the binary point over 6 places (1.1001000000000000000000 becomes 1100100.0000000000000000), determine the wth of each position containing a 1 (start from the binary point and wk left f the whole number and right f the fraction), and sum these values (64+32+4 = 100). To see what happens with a fraction, let s look at the conversion of π to a binary number to illustrate how we deal with the fractional ption of the number. Let s take π s value to be 3.141592654 (rounding it off to 9 fractional digits). First, the integer 3 is converted into binary, resulting in 11 2. Since the number will be presented in scientific notation, the exponent will be 1. The fractional part (0.141592654) is converted by repeatedly multiplying by 2 and collecting the resulting overflow integers, combining these integers from left to right (this must be repeated until we have the additional 21 binary digits that we need to fill the mantissa): Starting Number Number*2 Resulting integer New Binary Number 0.141592654 0.283185308 0 0 0.283185308 0.566370616 0 00 0.566370616 1.132741232 1 001 0.132741232 0.265482464 0 0010 0.265482464 0.530964928 0 00100 0.530964928 1.061929856 1 001001 0.061929856 0.123859712 0 0010010 0.123859712 0.247719424 0 00100100 0.247719424 0.495438848 0 001001000 0.495438848 0.990877696 0 0010010000 0.990877696 1.981755392 1 00100100001 0.981755392 1.963510784 1 001001000011 0.963510784 1.927021568 1 0010010000111 0.927021568 1.854043136 1 00100100001111 0.854043136 1.708086272 1 001001000011111 0.708086272 1.416172544 1 0010010000111111 0.416172544 0.832345088 0 00100100001111110 0.832345088 1.664690176 1 001001000011111101 0.664690176 1.329380352 1 0010010000111111011 0.329380352 0.658760704 0 00100100001111110110 0.658760704 1.317521408 1 001001000011111101101 2
The integer value, 11 2, is just concatenated with the fractional value, 001001000011111101101 2, to give 11001001000011111101101 2. The sign of the number is positive 0, and the exponent is 1 00000001 (when the extra zeros are added) resulting in the binary floating point number: 0 00000001 11001001000011111101101 00000000111001001000011111101101 Given these two numbers: 100 10 00000011011001000000000000000000 2 and π (3.14159265410) 00000000111001001000011111101101 2, we can find their sum in the following manner: shift the mantissa of the number with smaller exponent until the exponents are the same: 100 = 0 00000110 11001000000000000000000 Pi = 0 00000001 11001001000011111101101 Pi = 0 00000110 00000110010010000111111 then add the mantissas together. A carry might result which will make the mantissa 1 digit longer. If this happens, adjust the exponent and drop the rightmost binary digit of the mantissa so the mantissa remains 23 binary digits long. 100 = 0 00000110 11001000000000000000000 + Pi = 0 00000110 00000110010010000111111 -------------------------------------- 0 00000110 11001110010010000111111 Remember that the mantissa has a binary point after the left most digit: 1.1001110010010000111111. When we convert this number back to a decimal number, we first shift the binary point six places to the right: 1100111.0010010000111111 then convert the integer ption (1100111) to a decimal number 64+32+4+2+1=103 and the fractional ption (0.0010010000111111) to a fractional decimal number: 0.125+0.015625+0.00048828125+... You an assume that all numbers will be positive and all the exponents will be positive, so you will have an unsigned representation f the exponent. Your program should do the following: (a) read two variables of type double (b) represent each of them as an array of chars in which the first position is the sign, the following 8 positions represent the exponent, and the last 23 bits represent the mantissa. (c) add the numbers using this representation 3
(d) convert the result back to a double (e) print the result (f) use the following functions: // converts exponent from binary to decimal int bin2dec(char binary[]); // converts exponent from decimal to binary void dec2bin(int decimal, char binary[]); // fms a floating-point number in mantissa-exponent representation // from two arrays, // one representing the mantissa and the other one the exponent. // The first array is of size 23, the second one, 8, and the third one 32 void gather( char mantissa[], char exponent[], char matissa_exponent[]); // splits a floating point number from mantissa-exponent representation // into two arrays, // one f the exponent and one f the mantissa. // The first array is of size 32, the second one, 23, and the third one 8 void split(char mantissa_exponent[], char mantissa[], char exponent[]); // converts a double to mantissa-exponent representation void convert(double x, char mantissa_exponent[]); // converts a floating point number // from mantissa-exponent representation to double double convert_back(char mantissa_exponent[]); // shifts the mantissa a number of positions to the right void shift(char mantissa[], int n_pos); // aligns the mantissas of two numbers // so that they have the same exponent (the larger of the two) // and returns the exponent int align(int exp1, char mantissa1[], int exp2, char mantissa2[]); //adds two numbers in mantissa-exponent representation void add(char x1[], char x2[], char result[]); //any other functions you may need Test your functions individually befe trying to write the whole program at once. 4
Example: x1: 100 x2: 3.141592654 x1 + x2 = 103.141592654 Submission instructions: Submit 2 archived source code files on Sakai by July 2 11:59 PM. The files should be named float.c and histogram.c and saved in a folder named homewk4. Grading scale Comments: 5% Use of descriptive identifiers and symbolic constants: 5% Spacing and indentation: 5% Following submission instructions: 5% Problem1: 20% Problem2: 60% 5