Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/72.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C语言中的浮点加法_C_Floating Point - Fatal编程技术网

C语言中的浮点加法

C语言中的浮点加法,c,floating-point,C,Floating Point,我在C语言中的浮点加法有问题 我们得到了两个16位的数字,我们应该把它们相加,而不必担心它们的符号不同或指数为0或31的情况。 这是一个家庭作业,但我迟到了&我不明白为什么它不起作用 Algrothim有点像: 如果每个数字的不同返回0,则获取其符号位 获取每个数字的指数,找出较大的一个 2a。找出两者之间的区别 在第11位中,在每个尾数中加入一个隐式的 将指数较小的数字右移两个指数之差 取较大数字的符号和指数,或用移位尾数 返回结果 这是我的密码: LC3_Word FLADD(LC3_Wor

我在C语言中的浮点加法有问题

我们得到了两个16位的数字,我们应该把它们相加,而不必担心它们的符号不同或指数为0或31的情况。
这是一个家庭作业,但我迟到了&我不明白为什么它不起作用

Algrothim有点像:

  • 如果每个数字的不同返回0,则获取其符号位
  • 获取每个数字的指数,找出较大的一个 2a。找出两者之间的区别
  • 在第11位中,在每个尾数中加入一个隐式的
  • 将指数较小的数字右移两个指数之差
  • 取较大数字的符号和指数,或用移位尾数
  • 返回结果 这是我的密码:

    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
    代替,它们将由预处理器管理,并在需要时剥离,因为它们从未存在于代码中