C语言中的浮点加法
我在C语言中的浮点加法有问题 我们得到了两个16位的数字,我们应该把它们相加,而不必担心它们的符号不同或指数为0或31的情况。C语言中的浮点加法,c,floating-point,C,Floating Point,我在C语言中的浮点加法有问题 我们得到了两个16位的数字,我们应该把它们相加,而不必担心它们的符号不同或指数为0或31的情况。 这是一个家庭作业,但我迟到了&我不明白为什么它不起作用 Algrothim有点像: 如果每个数字的不同返回0,则获取其符号位 获取每个数字的指数,找出较大的一个 2a。找出两者之间的区别 在第11位中,在每个尾数中加入一个隐式的 将指数较小的数字右移两个指数之差 取较大数字的符号和指数,或用移位尾数 返回结果 这是我的密码: LC3_Word FLADD(LC3_Wor
这是一个家庭作业,但我迟到了&我不明白为什么它不起作用 Algrothim有点像:
LC3_Word FLADD(LC3_Word A, LC3_Word B)
{
// a debug variable, so we can turn errors on (debug = 1) and off (debug = 0)
int debug = 1;
// a default return value
LC3_Word returnValue = 0x0000;
if(debug)
{
printf("-----------------------------------\nBegin debug\n-----------------------------------\n");
printf("Return value: %x \n",returnValue);
printf("LC3 words: A %x, B %x\n",A,B);
}
// Masks to extract sign, exponent and fraction
LC3_Word signBitMask = 0x8000;
LC3_Word expMask = 0x7C000;
LC3_Word mantissaMask = 0x03FF;
// Mask to get the sign with the exponent
LC3_Word signExpMask = 0xFC00;
// A mask for the implicit 1
LC3_Word implicitOne = 0x0400;
// Getting the signs
LC3_Word signA = AND(signBitMask,A);
LC3_Word signB = AND(signBitMask,B);
// Getting the exponents
LC3_Word expA = AND(expMask,A);
LC3_Word expB = AND(expMask,B);
// Getting the mantissa's
LC3_Word mantA = AND(mantissaMask,A);
LC3_Word mantB = AND(mantissaMask,B);
if(debug)
{
printf("======================\n");
printf("\tSignBitMask: %x\n\texpMask: %x\n\tmantissaMask: %x\n",signBitMask,expMask,mantissaMask);
printf("\tSign EXP Mask: %x\n",signExpMask);
printf("\tsignA: %x, signB: %x\n", signA, signB);
printf("\tImplicit One Mask: %x\n",implicitOne);
printf("\tExp of a: %x, Exp of b: %x\n", expA, expB);
printf("\tmantissa of A: %x,mantissa of B: %x\n",mantA,mantB);
printf("======================\n");
}
// Getting each with it's sign bit and it's exponent
LC3_Word signExpA = AND(signExpMask,A);
LC3_Word signExpB = AND(signExpMask,B);
if(debug)
{
printf("signExpA of A: %i, signExpB of B: %i\n",signExpA,signExpB);
}
// if the signs are different, don't deal with this case
if(signA!=signB)
{
return 0;
}
// if the signs are the same, if not, just return the default value
if(signA==signB)
{
if(debug)
{
printf("We got into the if signs are the same block \n");
printf("Sign a: %i, Sign b: %i \n",signA,signB);
}
if(expA==expB)
{
if(debug)
{
printf("We got into the if exponents are the same block \n");
printf("Exp a: %x, Exp b: %x \n",expA,expB);
}
// exponents are the same
// Add Mantissa B to A
mantA = ADD(mantB,mantA);
if(debug)
{
printf("Addition of mantissa's %x\n",mantA);
}
// store into the return value the logical and of the mantissa with the existing exponent and sign
// might want to do an OR() not an AND()
returnValue = OR(signExpA,mantA);
} // end if the eponents are the same
else {
if(debug)
{
printf("The exponents are not the same block \n");
}
// Getting the size we need to shift by
int sizeToShift = 0;
if(expA>expB)
{
// Mask the mantissa of B with a implicit 1, then right shift
mantB = OR(implicitOne,mantB);
if(debug)
{
printf("The exponent a is > b\n");
}
// need to shift B, getting the size of how much
sizeToShift = expA-expB;
if(debug)
{
printf("size to shift: %d,\nmantissaB is: %x\n",sizeToShift,mantB);
}
// right shifting the mantissa of b
mantB = mantB >> sizeToShift;
if(debug)
{
printf("mantissa of b shifted: %x\n",mantB);
}
returnValue = OR(signExpA,ADD(mantA,mantB));
}// end if A > B in the exponent
else
{
// Mask the mantissa of A with a implicit 1, then right shift
mantA = OR(implicitOne,mantA);
if(debug)
{
printf("The exponent B is > A\n");
}
// need to shift A, getting the size of how much
sizeToShift = expB-expA;
if(debug)
{
printf("size to shift: %d,\nmantissaA is: %x\n",sizeToShift,mantA);
}
// right shifting the mantissa of A
mantA = mantA >> sizeToShift;
if(debug)
{
printf("mantissa of A shifted: %x\n",mantA);
}
returnValue = OR(signExpB,ADD(mantA,mantB));
}// end if B > A in the exponent
}// end if different exponents
} // end if the signs are the same
if(debug)
{
printf("Return Value %x\n",returnValue);
printf("-----------------------------------\nEnd debug\n-----------------------------------\n");
}
return returnValue;
}
这里是ADD,OR和
LC3_Word AND(LC3_Word A, LC3_Word B)
{
return (A&B);
}
LC3_Word OR(LC3_Word A, LC3_Word B)
{
return (A|B);
}
LC3_Word ADD(LC3_Word A, LC3_Word B)
{
return (A+B);
}
当我在浮点中加2+3时,得到的是3而不是5
有什么想法吗 我仍在阅读代码,但不应该 LC3_Word expMask=0x7C000 是 LC3_Word expMask=0x7C00 此外,您可以粘贴数字的二进制表示形式吗?所以我们很清楚这个算法是怎么实现的。如果您使用的是转换代码,那么该错误也可能在您的转换代码中
if(expA==expB)
{
if(debug)
{
printf("We got into the if exponents are the same block \n");
printf("Exp a: %x, Exp b: %x \n",expA,expB);
}
// exponents are the same
// Add Mantissa B to A
mantA = ADD(mantB,mantA);
if(debug)
{
printf("Addition of mantissa's %x\n",mantA);
}
// store into the return value the logical and of the mantissa with the existing exponent and sign
// might want to do an OR() not an AND()
returnValue = OR(signExpA,mantA);
} // end if the eponents are the same
这是错误的
你没有考虑到两个隐含的加在一起。当您添加2+3时,您添加的是1.0 x 2^1+1.1 x 2^1,并且忽略小数点之前的所有内容。。。因此,最终的结果是0.0+0.1=0.1,并在前面粘贴一个1。您还需要添加两个隐式的
试着这样做:
if(expA==expB)
{
if(debug)
{
printf("We got into the if exponents are the same block \n");
printf("Exp a: %x, Exp b: %x \n",expA,expB);
}
// exponents are the same
// Add Mantissa B to A
mantA = OR(implicitOne,mantA);
mantB = OR(implicitOne,mantB);
mantA = ADD(mantB,mantA);
// You need to normalize this now. But shifting to the right by 1 will suffice.
mantA >>= 1;
++expA;
// ... add the sign and you're done...
if(debug)
{
printf("Addition of mantissa's %x\n",mantA);
}
// store into the return value the logical and of the mantissa with the existing exponent and sign
// might want to do an OR() not an AND()
returnValue = OR(signExpA,mantA);
} // end if the eponents are the same
这些是16位浮点值?如果是这样,expMask上的零不是太多了吗?经过一个非常简短的观察,看起来你没有考虑到简单路径中的隐式“1”,其中的指数相等。你不应该使用单独的变量进行这样的调试。它可能会占用内存和/或CPU。如果在不同的地方有数百个这样的变量呢?你打算全部编辑它们吗?使用
#define
和#ifdef
代替,它们将由预处理器管理,并在需要时剥离,因为它们从未存在于代码中