Can someone please help with my code. It won\'t work and I have to turn it in in
ID: 3592468 • Letter: C
Question
Can someone please help with my code. It won't work and I have to turn it in in 1 hour.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct {
char data[16];
}super;
void super_mult(double op1, double op2, super* out);
super super_add(double op1, double op2);
char *super_print_bitseq(super op);
char *super_print_normalized(super op);
void double2sup(super* op, long long int in);
int isSuperZero(super op);
void main()
{
long long int casted1, casted2;
double input1, input2;
short temp;
super op1, op2, out;
printf("Input number: ");
// printf("size of int%d ", sizeof(long));
scanf_s("%lf %lf", &input1, &input2);
memcpy(&casted1, &input1, sizeof(double));
memcpy(&casted2, &input2, sizeof(double));
double2sup(&op1, casted1);
double2sup(&op2, casted2);
printf("%e %f %llx ", input1, input1, casted1);
printf("%s ", super_print_bitseq(op1));
printf("%s ", super_print_normalized(op1));
printf("%e %f %llx ", input2, input2, casted2);
printf("%s ", super_print_bitseq(op2));
printf("%s ", super_print_normalized(op2));
super_mult(input1, input2, &out);
printf("%s ", super_print_bitseq(out));
printf("%s ", super_print_normalized(out));
}
void double2sup(super* op, long long int in)
{
unsigned short exp_temp, exp;
unsigned char sign;
long long int in_temp = in;
/* Clear all data */
for (int i = 0; i < 16; i++)
op->data[i] = 0;
if (in == 0) return;
if (in_temp == 0x8000000000000000) {
op->data[15] |= 0x80;
return;
}
/* Converting Exp for double to that for super*/
exp_temp = (unsigned short)(in_temp >> 52)&0x0fff;
exp = (exp_temp & 0x7ff) + 15360; //exponent
op->data[14] = exp & 0x00ff;
op->data[15] = (exp >> 8) & 0x00ff;
if (exp_temp & 0x800) op->data[15] |= 0x80; //sign
/* Copying fraction of double (bit 0 ~ bit 51) to that of super (bit 60~111) */
unsigned char c;
c = in_temp & 0x0f;
op->data[7] = c << 4;
in_temp >>= 4;
op->data[8] = in_temp & 0xff;
in_temp >>= 8;
op->data[9] = in_temp & 0xff;
in_temp >>= 8;
op->data[10] = in_temp & 0xff;
in_temp >>= 8;
op->data[11] = in_temp & 0xff;
in_temp >>= 8;
op->data[12] = in_temp & 0xff;
in_temp >>= 8;
op->data[13] = in_temp & 0xff;
/* Convert exponent of */
}
char *super_print_bitseq(super op)
{
/* The length is 144 = 128 + 15 (spaces) + 1 (end of string)*/
static char dat[144];
int i,ri;
for (i = 0; i < 16; i++)
{
ri = 16-i;
//printf("%x ", op.data[i]);
dat[ri*9 - 1] = ' ';
dat[ri*9 - 2] = (op.data[i] & 0x01) ? '1': '0';
dat[ri*9 - 3] = (op.data[i] & 0x02) ? '1' : '0';
dat[ri*9 - 4] = (op.data[i] & 0x04) ? '1' : '0';
dat[ri*9 - 5] = (op.data[i] & 0x08) ? '1' : '0';
dat[ri*9 - 6] = (op.data[i] & 0x10) ? '1' : '0';
dat[ri*9 - 7] = (op.data[i] & 0x20) ? '1' : '0';
dat[ri*9 - 8] = (op.data[i] & 0x40) ? '1' : '0';
dat[ri*9 - 9] = (op.data[i] & 0x80) ? '1' : '0';
}
dat[143] = '';
char *ret;
ret = (char*)&dat;
return ret;
}
char *super_print_normalized(super op)
{
static char dat[200];
int idx = 0,temp, digit, exp;
char *ret;
if (isSuperZero(op)) {
dat[0] = '0';
dat[1] = '';
ret = (char*)&dat;
return ret;
}
if (op.data[15] & 0x80) {
dat[idx++] = '-';
dat[idx++] = '1';
dat[idx++] = '.';
}
else {
dat[idx++] = '1';
dat[idx++] = '.';
}
for (int i = 0; i < 14; i++)
{
int ri = 13 - i;
dat[idx++] = op.data[ri] & 0x80 ? '1' : '0';
dat[idx++] = op.data[ri] & 0x40 ? '1' : '0';
dat[idx++] = op.data[ri] & 0x20 ? '1' : '0';
dat[idx++] = op.data[ri] & 0x10 ? '1' : '0';
dat[idx++] = op.data[ri] & 0x08 ? '1' : '0';
dat[idx++] = op.data[ri] & 0x04 ? '1' : '0';
dat[idx++] = op.data[ri] & 0x02 ? '1' : '0';
dat[idx++] = op.data[ri] & 0x01 ? '1' : '0';
}
dat[idx++] = ' ';
dat[idx++] = 'x';
dat[idx++] = ' ';
dat[idx++] = '2';
dat[idx++] = '^';
exp = op.data[15] & 0x07f;
exp = exp << 8;
exp |= (op.data[14]&0x00ff);
digit = exp - 16383;
temp = digit & 0x00007fff;
if (temp == 0) {
dat[idx++] = '0';
}
else {
if (digit < 0) {
dat[idx++] = '-';
digit *= -1;
}
temp = digit / 10000;
digit -= temp * 10000;
if (temp) dat[idx++] = (char)(temp)+'0';
temp = digit / 1000;
digit -= temp * 1000;
if (temp) dat[idx++] = (char)(temp)+'0';
temp = digit / 100;
digit -= temp * 100;
if (temp) dat[idx++] = (char)(temp)+'0';
temp = digit / 10;
digit -= temp * 10;
if (temp) dat[idx++] = (char)(temp)+'0';
temp = digit;
if (temp) dat[idx++] = (char)(temp)+'0';
}
dat[idx] = '';
ret = (char*)&dat;
return ret;
}
int isSuperZero(super op)
{
for (int i = 0; i < 14; i++)
{
if (op.data[i] != (char)0) return 0;
}
char temp = op.data[15] & (char)0x7f;
if ( temp != 0) return 0;
return 1;
}
void super_mult(double op1, double op2, super* out)
{
super sop1, sop2 ;
int f1[113], f2[113], f3[113];
char sign = 0, temp1, temp2;
long long int casted1, casted2;
short exp, stemp1, stemp2;
/* Make two doubles to supers */
memcpy(&casted1, &op1, sizeof(double));
memcpy(&casted2, &op2, sizeof(double));
double2sup(&sop1, casted1);
double2sup(&sop2, casted2);
/* Decide sign */
temp1 = sop1.data[15] & 0x80;
temp2 = sop2.data[15] & 0x80;
if (temp1 != temp2) sign = 0x80;
/* Add exponent*/
stemp1 = (sop1.data[15] & 0x007f);
stemp1 <<= 8;
stemp1 |= (sop1.data[14] & 0x00ff);
stemp2 = (sop2.data[15] & 0x007f);
stemp2 <<= 8;
stemp2 |= (sop2.data[14] & 0x00ff);
exp = stemp1 + stemp2 - 16383;
/* bit to char for calculation */
f1[112] = 1;
f2[112] = 1;
for (int i = 0; i < 113; i++) f3[i] = 0;
for (int i = 0; i < 14; i++) {
f1[i * 8] = sop1.data[i] & 0x01 ? 1 : 0;
f1[i * 8 + 1] = sop1.data[i] & 0x02 ? 1 : 0;
f1[i * 8 + 2] = sop1.data[i] & 0x04 ? 1 : 0;
f1[i * 8 + 3] = sop1.data[i] & 0x08 ? 1 : 0;
f1[i * 8 + 4] = sop1.data[i] & 0x10 ? 1 : 0;
f1[i * 8 + 5] = sop1.data[i] & 0x20 ? 1 : 0;
f1[i * 8 + 6] = sop1.data[i] & 0x40 ? 1 : 0;
f1[i * 8 + 7] = sop1.data[i] & 0x80 ? 1 : 0;
f2[i * 8] = sop2.data[i] & 0x01 ? 1 : 0;
f2[i * 8 + 1] = sop2.data[i] & 0x02 ? 1 : 0;
f2[i * 8 + 2] = sop2.data[i] & 0x04 ? 1 : 0;
f2[i * 8 + 3] = sop2.data[i] & 0x08 ? 1 : 0;
f2[i * 8 + 4] = sop2.data[i] & 0x10 ? 1 : 0;
f2[i * 8 + 5] = sop2.data[i] & 0x20 ? 1 : 0;
f2[i * 8 + 6] = sop2.data[i] & 0x40 ? 1 : 0;
f2[i * 8 + 7] = sop2.data[i] & 0x80 ? 1 : 0;
}
/* Multiply fraction */
for (int i = 0; i < 113; i++) {
for (int j = 112; j >= 0 + i; j--)
{
f3[j + i] += f1[j] * f2[112 - i];
}
for (int k = 0; k < 112; k++)
{
if (f3[k] == 2) {
f3[k] = 0;
f3[k + 1]++;
}
else if (f3[k] == 3) {
f3[k] = 1;
f3[k + 1]++;
}
}
if (f3[112] == 2) {
exp++;
for (int k = 0; k < 111; k++)
{
f3[k] = f3[k + 1];
}
f3[111] = 0;
f3[112] = 1;
}
}
for (int i = 0; i < 14; i++) {
out->data[i] = f3[i * 8 + 0] + f3[i * 8 + 1] * 2 + f3[i * 8 + 2] * 4 + f3[i * 8 + 3] * 8 + f3[i * 8 + 4] * 16 + f3[i * 8 + 5] * 32 + f3[i * 8 + 6] * 64 + f3[i * 8 + 7] * 128;
}
out->data[14] = exp & 0x00ff;
out->data[15] = (exp >> 8) & 0x00ff;
out->data[15] |= sign; //sign
}
super super_add(double op1, double op2)
{
}
The problem is this and I hope someone can finish this code for me. It is so hard. I've been doing it for a long time....
Can anyone help?
Design and implement the multiplication and addition functions between two double precision operands. The return values from your functions must be 128-bit floating point data typed, and thus no overflow occurs. Write a test program that obtains two double precision operands through the standard input and prints both the sum and multiplication of the two operands by using the implemented functions. 2. Details As learned in our class, overflow, which produces "infinity", may occur when a computer conducts multiplication or addition over two floating point variables unless the result is stored in a larger data typed variable. Therefore, if you do not want infinity outcomes from arithmetic operations over 32-bit float variables, you can cast the operands to 64- bit double and conduct the operation. However, this workaround cannot be applied to arithmetic between two double precision operands since the standard C does not provide a 128-bit floating point data type. Therefore, you must define your own 128-bit floating point data type and supporting functions for it. The internal structure of the 128-bit floating point data type, which we call super precision from now on, consists of 1 bit for sign, 15 bits for exponent and 112 bits for significand, from MS to LSB. They are organized in a character array named data, in the little-endian form. The super precision data type is defined as follows typedef struct ! char data 16]; super There are two arithmetic functions that return super typed values. multiplication of two doubles * super super_mult(double opl, doble op3); /addition of two doubles * super super add(double opl, double op3); Because the printffunction does not know how to print a super typed variable, you need two additional functions that produce strings out of a super typed variable. The first function returns the bit sequence of the operand, and the other one returns the normalized form of the operand in binary (for example, 1.010010011100 x 241203). returns the bit sequence string* char *super print bitseq(super op); /* returns the string of the normalized form in binary char *super print_normalized(super op); Restriction: Your data must be aligned in little endian so that the LSB must be accommodated in data 0] and the MSB in data[3]. Do not use long double or any non- standard floating point data types. Also, use of any arbitrary precision arithmetic libraries are prohibited.Explanation / Answer
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct {
char data[16];
}super;
void super_mult(double op1, double op2, super* out);
super super_add(double op1, double op2);
char *super_print_bitseq(super op);
char *super_print_normalized(super op);
void double2sup(super* op, long long int in);
int isSuperZero(super op);
void main()
{
long long int casted1, casted2;
double input1, input2;
short temp;
super op1, op2, out;
printf("Input number: ");
// printf("size of int%d ", sizeof(long));
scanf_s("%lf %lf", &input1, &input2);
memcpy(&casted1, &input1, sizeof(double));
memcpy(&casted2, &input2, sizeof(double));
double2sup(&op1, casted1);
double2sup(&op2, casted2);
printf("%e %f %llx ", input1, input1, casted1);
printf("%s ", super_print_bitseq(op1));
printf("%s ", super_print_normalized(op1));
printf("%e %f %llx ", input2, input2, casted2);
printf("%s ", super_print_bitseq(op2));
printf("%s ", super_print_normalized(op2));
super_mult(input1, input2, &out);
printf("%s ", super_print_bitseq(out));
printf("%s ", super_print_normalized(out));
}
void double2sup(super* op, long long int in)
{
unsigned short exp_temp, exp;
unsigned char sign;
long long int in_temp = in;
/* Clear all data */
for (int i = 0; i < 16; i++)
op->data[i] = 0;
if (in == 0) return;
if (in_temp == 0x8000000000000000) {
op->data[15] |= 0x80;
return;
}
/* Converting Exp for double to that for super*/
exp_temp = (unsigned short)(in_temp >> 52)&0x0fff;
exp = (exp_temp & 0x7ff) + 15360; //exponent
op->data[14] = exp & 0x00ff;
op->data[15] = (exp >> 8) & 0x00ff;
if (exp_temp & 0x800) op->data[15] |= 0x80; //sign
/* Copying fraction of double (bit 0 ~ bit 51) to that of super (bit 60~111) */
unsigned char c;
c = in_temp & 0x0f;
op->data[7] = c << 4;
in_temp >>= 4;
op->data[8] = in_temp & 0xff;
in_temp >>= 8;
op->data[9] = in_temp & 0xff;
in_temp >>= 8;
op->data[10] = in_temp & 0xff;
in_temp >>= 8;
op->data[11] = in_temp & 0xff;
in_temp >>= 8;
op->data[12] = in_temp & 0xff;
in_temp >>= 8;
op->data[13] = in_temp & 0xff;
/* Convert exponent of */
}
char *super_print_bitseq(super op)
{
/* The length is 144 = 128 + 15 (spaces) + 1 (end of string)*/
static char dat[144];
int i,ri;
for (i = 0; i < 16; i++)
{
ri = 16-i;
//printf("%x ", op.data[i]);
dat[ri*9 - 1] = ' ';
dat[ri*9 - 2] = (op.data[i] & 0x01) ? '1': '0';
dat[ri*9 - 3] = (op.data[i] & 0x02) ? '1' : '0';
dat[ri*9 - 4] = (op.data[i] & 0x04) ? '1' : '0';
dat[ri*9 - 5] = (op.data[i] & 0x08) ? '1' : '0';
dat[ri*9 - 6] = (op.data[i] & 0x10) ? '1' : '0';
dat[ri*9 - 7] = (op.data[i] & 0x20) ? '1' : '0';
dat[ri*9 - 8] = (op.data[i] & 0x40) ? '1' : '0';
dat[ri*9 - 9] = (op.data[i] & 0x80) ? '1' : '0';
}
dat[143] = '';
char *ret;
ret = (char*)&dat;
return ret;
}
char *super_print_normalized(super op)
{
static char dat[200];
int idx = 0,temp, digit, exp;
char *ret;
if (isSuperZero(op)) {
dat[0] = '0';
dat[1] = '';
ret = (char*)&dat;
return ret;
}
if (op.data[15] & 0x80) {
dat[idx++] = '-';
dat[idx++] = '1';
dat[idx++] = '.';
}
else {
dat[idx++] = '1';
dat[idx++] = '.';
}
for (int i = 0; i < 14; i++)
{
int ri = 13 - i;
dat[idx++] = op.data[ri] & 0x80 ? '1' : '0';
dat[idx++] = op.data[ri] & 0x40 ? '1' : '0';
dat[idx++] = op.data[ri] & 0x20 ? '1' : '0';
dat[idx++] = op.data[ri] & 0x10 ? '1' : '0';
dat[idx++] = op.data[ri] & 0x08 ? '1' : '0';
dat[idx++] = op.data[ri] & 0x04 ? '1' : '0';
dat[idx++] = op.data[ri] & 0x02 ? '1' : '0';
dat[idx++] = op.data[ri] & 0x01 ? '1' : '0';
}
dat[idx++] = ' ';
dat[idx++] = 'x';
dat[idx++] = ' ';
dat[idx++] = '2';
dat[idx++] = '^';
exp = op.data[15] & 0x07f;
exp = exp << 8;
exp |= (op.data[14]&0x00ff);
digit = exp - 16383;
temp = digit & 0x00007fff;
if (temp == 0) {
dat[idx++] = '0';
}
else {
if (digit < 0) {
dat[idx++] = '-';
digit *= -1;
}
temp = digit / 10000;
digit -= temp * 10000;
if (temp) dat[idx++] = (char)(temp)+'0';
temp = digit / 1000;
digit -= temp * 1000;
if (temp) dat[idx++] = (char)(temp)+'0';
temp = digit / 100;
digit -= temp * 100;
if (temp) dat[idx++] = (char)(temp)+'0';
temp = digit / 10;
digit -= temp * 10;
if (temp) dat[idx++] = (char)(temp)+'0';
temp = digit;
if (temp) dat[idx++] = (char)(temp)+'0';
}
dat[idx] = '';
ret = (char*)&dat;
return ret;
}
int isSuperZero(super op)
{
for (int i = 0; i < 14; i++)
{
if (op.data[i] != (char)0) return 0;
}
char temp = op.data[15] & (char)0x7f;
if ( temp != 0) return 0;
return 1;
}
void super_mult(double op1, double op2, super* out)
{
super sop1, sop2 ;
int f1[113], f2[113], f3[113];
char sign = 0, temp1, temp2;
long long int casted1, casted2;
short exp, stemp1, stemp2;
/* Make two doubles to supers */
memcpy(&casted1, &op1, sizeof(double));
memcpy(&casted2, &op2, sizeof(double));
double2sup(&sop1, casted1);
double2sup(&sop2, casted2);
/* Decide sign */
temp1 = sop1.data[15] & 0x80;
temp2 = sop2.data[15] & 0x80;
if (temp1 != temp2) sign = 0x80;
/* Add exponent*/
stemp1 = (sop1.data[15] & 0x007f);
stemp1 <<= 8;
stemp1 |= (sop1.data[14] & 0x00ff);
stemp2 = (sop2.data[15] & 0x007f);
stemp2 <<= 8;
stemp2 |= (sop2.data[14] & 0x00ff);
exp = stemp1 + stemp2 - 16383;
/* bit to char for calculation */
f1[112] = 1;
f2[112] = 1;
for (int i = 0; i < 113; i++) f3[i] = 0;
for (int i = 0; i < 14; i++) {
f1[i * 8] = sop1.data[i] & 0x01 ? 1 : 0;
f1[i * 8 + 1] = sop1.data[i] & 0x02 ? 1 : 0;
f1[i * 8 + 2] = sop1.data[i] & 0x04 ? 1 : 0;
f1[i * 8 + 3] = sop1.data[i] & 0x08 ? 1 : 0;
f1[i * 8 + 4] = sop1.data[i] & 0x10 ? 1 : 0;
f1[i * 8 + 5] = sop1.data[i] & 0x20 ? 1 : 0;
f1[i * 8 + 6] = sop1.data[i] & 0x40 ? 1 : 0;
f1[i * 8 + 7] = sop1.data[i] & 0x80 ? 1 : 0;
f2[i * 8] = sop2.data[i] & 0x01 ? 1 : 0;
f2[i * 8 + 1] = sop2.data[i] & 0x02 ? 1 : 0;
f2[i * 8 + 2] = sop2.data[i] & 0x04 ? 1 : 0;
f2[i * 8 + 3] = sop2.data[i] & 0x08 ? 1 : 0;
f2[i * 8 + 4] = sop2.data[i] & 0x10 ? 1 : 0;
f2[i * 8 + 5] = sop2.data[i] & 0x20 ? 1 : 0;
f2[i * 8 + 6] = sop2.data[i] & 0x40 ? 1 : 0;
f2[i * 8 + 7] = sop2.data[i] & 0x80 ? 1 : 0;
}
/* Multiply fraction */
for (int i = 0; i < 113; i++) {
for (int j = 112; j >= 0 + i; j--)
{
f3[j + i] += f1[j] * f2[112 - i];
}
for (int k = 0; k < 112; k++)
{
if (f3[k] == 2) {
f3[k] = 0;
f3[k + 1]++;
}
else if (f3[k] == 3) {
f3[k] = 1;
f3[k + 1]++;
}
}
if (f3[112] == 2) {
exp++;
for (int k = 0; k < 111; k++)
{
f3[k] = f3[k + 1];
}
f3[111] = 0;
f3[112] = 1;
}
}
for (int i = 0; i < 14; i++) {
out->data[i] = f3[i * 8 + 0] + f3[i * 8 + 1] * 2 + f3[i * 8 + 2] * 4 + f3[i * 8 + 3] * 8 + f3[i * 8 + 4] * 16 + f3[i * 8 + 5] * 32 + f3[i * 8 + 6] * 64 + f3[i * 8 + 7] * 128;
}
out->data[14] = exp & 0x00ff;
out->data[15] = (exp >> 8) & 0x00ff;
out->data[15] |= sign; //sign
}
super super_add(double op1, double op2)
{
}