我在使用C中的浮点加法时遇到了问题。
我们给了两个16位数字,我们应该添加它们而不用担心它们的符号不同或指数为0或31的情况。
这是一个家庭作业,但我迟到了。我无法弄清楚为什么它不起作用。
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和AND,
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。
有什么想法吗?
答案 0 :(得分: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 = 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
答案 1 :(得分:0)
我仍在阅读代码,但不应该
LC3_Word expMask = 0x7C000;
是
LC3_Word expMask = 0x7C00;?
另外,您可以粘贴数字的二进制表示吗?正因为如此,我们清楚通过这个算法得到了什么。如果您使用的是错误,也可能在您的转换代码中...