⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 float.c

📁 WinCE5.0部分核心源码
💻 C
📖 第 1 页 / 共 5 页
字号:
            // to form the total product.
            //
            // The two mantissa values are preshifted such that the final
            // result is properly aligned.
            //

        case FLOAT_MULTIPLY:
            if (Format == FORMAT_SINGLE) {

                //
                // Reorder the operands according to their exponent value.
                //

                if (SingleOperand2.Exponent > SingleOperand1.Exponent) {
                    SingleOperand3 = SingleOperand2;
                    SingleOperand2 = SingleOperand1;
                    SingleOperand1 = SingleOperand3;
                }

                //
                // If the first operand is infinite and the second operand is
                // zero, then an invalid operation is specified.
                //

                if ((SingleOperand1.Infinity != FALSE) &&
                    (SingleOperand2.Infinity == FALSE) &&
                    (SingleOperand2.Mantissa == 0)) {
                    return KiInvalidOperationSingle(&ContextBlock,
                                                    FALSE,
                                                    &SingleOperand1,
                                                    &SingleOperand2);

                }

                //
                // Preshift the operand mantissas so the result will be a
                // properly aligned 64-bit value and then unsigned multiply
                // the two mantissa values. The single result is the high part
                // of the 64-bit product and the sticky bits are the low part
                // of the 64-bit product.
                //

                LargeResult.QuadPart = UInt32x32To64(SingleOperand1.Mantissa << (32 - 26),
                                                     SingleOperand2.Mantissa << 1);

                SingleOperand1.Mantissa = LargeResult.HighPart;
                StickyBits = LargeResult.LowPart;

                //
                // Compute the sign and exponent of the result.
                //

                SingleOperand1.Sign ^= SingleOperand2.Sign;
                SingleOperand1.Exponent +=
                            SingleOperand2.Exponent - SINGLE_EXPONENT_BIAS;

                //
                // Normalize and store the result value.
                //

                return KiNormalizeSingle(&ContextBlock,
                                         &SingleOperand1,
                                         StickyBits);

            } else if (Format == FORMAT_DOUBLE) {

                //
                // Reorder the operands according to their exponent value.
                //

                if (DoubleOperand2.Exponent > DoubleOperand1.Exponent) {
                    DoubleOperand3 = DoubleOperand2;
                    DoubleOperand2 = DoubleOperand1;
                    DoubleOperand1 = DoubleOperand3;
                }

                //
                // If the first operand is infinite and the second operand is
                // zero, then an invalid operation is specified.
                //

                if ((DoubleOperand1.Infinity != FALSE) &&
                    (DoubleOperand2.Infinity == FALSE) &&
                    (DoubleOperand2.MantissaHigh == 0)) {
                    return KiInvalidOperationDouble(&ContextBlock,
                                                    FALSE,
                                                    &DoubleOperand1,
                                                    &DoubleOperand2);

                }

                //
                // Preshift the operand mantissas so the result will be a
                // properly aligned 128-bit value and then unsigned multiply
                // the two mantissa values. The double result is the high part
                // of the 128-bit product and the sticky bits are the low part
                // of the 128-bit product.
                //

                DoubleOperand1.MantissaHigh =
                        (DoubleOperand1.MantissaHigh << 1) |
                                (DoubleOperand1.MantissaLow >> 31);

                DoubleOperand1.MantissaLow <<= 1;
                DoubleOperand2.MantissaHigh =
                        (DoubleOperand2.MantissaHigh << (64 - 55)) |
                                (DoubleOperand2.MantissaLow >> (32 - (64 -55)));

                DoubleOperand2.MantissaLow <<= (64 - 55);

                //
                // The 128-bit product is formed by mutiplying and adding
                // all the cross product values.
                //
                // Consider the operands (A and B) as being composed of two
                // parts Ahigh, Alow, Bhigh, and Blow. The cross product sum
                // is then:
                //
                //       Ahigh * Bhigh * 2^64 +
                //              Ahigh * Blow * 2^32 +
                //              Alow * Bhigh * 2^32 +
                //                              Alow * Blow
                //

                AhighBhigh.QuadPart = UInt32x32To64(DoubleOperand1.MantissaHigh,
                                                    DoubleOperand2.MantissaHigh);

                AhighBlow.QuadPart = UInt32x32To64(DoubleOperand1.MantissaHigh,
                                                   DoubleOperand2.MantissaLow);

                AlowBhigh.QuadPart = UInt32x32To64(DoubleOperand1.MantissaLow,
                                                   DoubleOperand2.MantissaHigh);

                AlowBlow.QuadPart = UInt32x32To64(DoubleOperand1.MantissaLow,
                                                  DoubleOperand2.MantissaLow);

                AlowBlow.HighPart += AhighBlow.LowPart;
                if (AlowBlow.HighPart < AhighBlow.LowPart) {
                    Carry1 = 1;

                } else {
                    Carry1 = 0;
                }

                AlowBlow.HighPart += AlowBhigh.LowPart;
                if (AlowBlow.HighPart < AlowBhigh.LowPart) {
                    Carry1 += 1;
                }

                DoubleOperand1.MantissaLow = AhighBlow.HighPart + Carry1;
                if (DoubleOperand1.MantissaLow < Carry1) {
                    Carry2 = 1;

                } else {
                    Carry2 = 0;
                }

                DoubleOperand1.MantissaLow += AlowBhigh.HighPart;
                if (DoubleOperand1.MantissaLow < AlowBhigh.HighPart) {
                    Carry2 += 1;
                }

                DoubleOperand1.MantissaLow += AhighBhigh.LowPart;
                if (DoubleOperand1.MantissaLow < AhighBhigh.LowPart) {
                    Carry2 += 1;
                }

                DoubleOperand1.MantissaHigh = AhighBhigh.HighPart + Carry2;
                StickyBits = AlowBlow.HighPart | AlowBlow.LowPart;

                //
                // Compute the sign and exponent of the result.
                //

                DoubleOperand1.Sign ^= DoubleOperand2.Sign;
                DoubleOperand1.Exponent +=
                            DoubleOperand2.Exponent - DOUBLE_EXPONENT_BIAS;

                //
                // Normalize and store the result value.
                //

                return KiNormalizeDouble(&ContextBlock,
                                         &DoubleOperand1,
                                         StickyBits);

            } else {
                break;
            }

            //
            // Floating divide operation.
            //
            // Floating division is accomplished by repeated subtract using
            // a single one-bit-at-a-time algorithm. The number of division
            // steps performed is equal to the mantissa size plus one guard
            // bit.
            //
            // The sticky bits are the remainder after the specified number
            // of division steps.
            //

        case FLOAT_DIVIDE:
            if (Format == FORMAT_SINGLE) {

                //
                // If the first operand is infinite and the second operand
                // is infinite, or both operands are zero, then an invalid
                // operation is specified.
                //

                if (((SingleOperand1.Infinity != FALSE) &&
                    (SingleOperand2.Infinity != FALSE)) ||
                    ((SingleOperand1.Infinity == FALSE) &&
                    (SingleOperand1.Mantissa == 0) &&
                    (SingleOperand2.Infinity == FALSE) &&
                    (SingleOperand2.Mantissa == 0))) {
                    return KiInvalidOperationSingle(&ContextBlock,
                                                    FALSE,
                                                    &SingleOperand1,
                                                    &SingleOperand2);

                }

                //
                // If the second operand is zero, then a divide by zero
                // operation is specified.
                //

                if ((SingleOperand2.Infinity == FALSE) &&
                    (SingleOperand2.Mantissa == 0)) {
                    return KiDivideByZeroSingle(&ContextBlock,
                                                &SingleOperand1,
                                                &SingleOperand2);
                }

                //
                // If the first operand is infinite, then the result is
                // infinite. Otherwise, if the second operand is infinite,
                // then the result is zero (note that both operands cannot
                // be infinite).
                //

                if (SingleOperand1.Infinity != FALSE) {
                    SingleOperand1.Sign ^= SingleOperand2.Sign;
                    return KiNormalizeSingle(&ContextBlock,
                                             &SingleOperand1,
                                             0);

                } else if (SingleOperand2.Infinity != FALSE) {
                    SingleOperand1.Sign ^= SingleOperand2.Sign;
                    SingleOperand1.Exponent = 0;
                    SingleOperand1.Mantissa = 0;
                    return KiNormalizeSingle(&ContextBlock,
                                             &SingleOperand1,
                                             0);

                }

                //
                // Perform divide operation by repeating a single bit
                // divide step 26 iterations.
                //

                SingleOperand3.Mantissa = 0;
                for (Index = 0; Index < 26; Index += 1) {
                    SingleOperand3.Mantissa <<=1;
                    if (SingleOperand1.Mantissa >= SingleOperand2.Mantissa) {
                        SingleOperand1.Mantissa -= SingleOperand2.Mantissa;
                        SingleOperand3.Mantissa |= 1;
                    }

                    SingleOperand1.Mantissa <<= 1;
                }

                //
                // Compute the sign and exponent of the result.
                //

                SingleOperand3.Sign = SingleOperand1.Sign ^ SingleOperand2.Sign;
                SingleOperand3.Exponent = SingleOperand1.Exponent -
                                SingleOperand2.Exponent + SINGLE_EXPONENT_BIAS;

                //
                // Normalize and store the result value.
                //

                SingleOperand3.Infinity = FALSE;
                SingleOperand3.Nan = FALSE;
                return KiNormalizeSingle(&ContextBlock,
                                         &SingleOperand3,
                                         SingleOperand1.Mantissa);

            } else if (Format == FORMAT_DOUBLE) {

                //
                // If the first operand is infinite and the second operand
                // is infinite, or both operands are zero, then an invalid
                // operation is specified.
                //

                if (((DoubleOperand1.Infinity != FALSE) &&
                    (DoubleOperand2.Infinity != FALSE)) ||
                    ((DoubleOperand1.Infinity == FALSE) &&
                    (DoubleOperand1.MantissaHigh == 0) &&
                    (DoubleOperand2.Infinity == FALSE) &&
                    (DoubleOperand2.MantissaHigh == 0))) {
                    return KiInvalidOperationDouble(&ContextBlock,
                                                    FALSE,
                                                    &DoubleOperand1,
                                                    &DoubleOperand2);

                }

                //
                // If the second operand is zero, then a divide by zero
                // operation is specified.
                //

                if ((DoubleOperand2.Infinity == FALSE) &&
                    (DoubleOperand2.MantissaHigh == 0)) {
                    return KiDivideByZeroDouble(&ContextBlock,
                                                &DoubleOperand1,
                                                &DoubleOperand2);
                }

                //
                // If the first operand is infinite, then the result is
                // infinite. Otherwise, if the second operand is infinite,
                // then the result is zero (note that both operands cannot
                // be infinite).
                //

                if (DoubleOperand1.Infinity != FALSE) {
                    DoubleOperand1.Sign ^= DoubleOperand2.Sign;
                    return KiNormalizeDouble(&ContextBlock,
                                             &DoubleOperand1,
                                             0);

                } else if (DoubleOperand2.Infinity != FALSE) {
                    DoubleOperand1.Sign ^= DoubleOperand2.Sign;
  

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -