C中的浮点加法

时间:2012-02-28 02:03:58

标签: c floating-point

我在使用C中的浮点加法时遇到了问题。

我们给了两个16位数字,我们应该添加它们而不用担心它们的符号不同或指数为0或31的情况。
这是一个家庭作业,但我迟到了。我无法弄清楚为什么它不起作用。

Algrothim有点像:

  1. 获取每个数字的符号位,如果它们的返回值不同为0.
  2. 获取每个数字的指数,找到更大的数字 2A。找出两者之间的区别。
  3. 在第11位中将隐含的一个放入每个尾数的
  4. 使用较小的指数右移数字乘以指数的差值
  5. 取较大数字的符号和指数或带有移位的尾数。
  6. 返回结果。
  7. 这是我的代码:

    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。

    有什么想法吗?

2 个答案:

答案 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;?

另外,您可以粘贴数字的二进制表示吗?正因为如此,我们清楚通过这个算法得到了什么。如果您使用的是错误,也可能在您的转换代码中...