簡體   English   中英

C語言中的浮點加法

[英]Floating Point Addition in C

我在C語言中使用浮點加法時遇到麻煩。

我們給了兩個16位數字,我們應該添加它們而不用擔心它們的符號不同或指數為0或31的情況。
這是一項家庭作業,但是我遲到了,我不知道為什么它不起作用。

Algrothim的外觀如下:

  1. 如果每個數字的符號位不同,則返回0。
  2. 獲取每個數字的指數,找到較大的2a。 找出兩者之間的區別。
  3. 在第11位中,每個尾數中都隱含一個
  4. 將指數較小的數字右移指數的差
  5. 取較大數字的符號和指數,或將其與移位的尾數相乘。
  6. 返回結果。

這是我的代碼:

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。

有任何想法嗎?

    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 

我仍在閱讀代碼,但不應

LC3_Word expMask = 0x7C000;

LC3_Word expMask = 0x7C00 ;?

另外,您可以粘貼數字的二進制表示形式嗎? 這樣我們就很清楚此算法要處理的內容。 如果您使用的是此錯誤,也可能在轉換代碼中...

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM