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

📄 float.c

📁 可用于嵌入式编程学习
💻 C
📖 第 1 页 / 共 5 页
字号:
            } 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;
                    DoubleOperand1.Exponent = 0;
                    DoubleOperand1.MantissaHigh = 0;
                    DoubleOperand1.MantissaLow = 0;
                    return KiNormalizeDouble(&ContextBlock,
                                             &DoubleOperand1,
                                             0);

                }

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

                DoubleDividend.LowPart = DoubleOperand1.MantissaLow;
                DoubleDividend.HighPart = DoubleOperand1.MantissaHigh;
                DoubleDivisor.LowPart = DoubleOperand2.MantissaLow;
                DoubleDivisor.HighPart = DoubleOperand2.MantissaHigh;
                DoubleQuotient.LowPart = 0;
                DoubleQuotient.HighPart = 0;
                for (Index = 0; Index < 55; Index += 1) {
                    DoubleQuotient.HighPart =
                                (DoubleQuotient.HighPart << 1) |
                                                DoubleQuotient.LowPart >> 31;

                    DoubleQuotient.LowPart <<= 1;
                    if (DoubleDividend.QuadPart >= DoubleDivisor.QuadPart) {
                        DoubleDividend.QuadPart -= DoubleDivisor.QuadPart;
                        DoubleQuotient.LowPart |= 1;
                    }

                    DoubleDividend.HighPart =
                                (DoubleDividend.HighPart << 1) |
                                                DoubleDividend.LowPart >> 31;

                    DoubleDividend.LowPart <<= 1;
                }

                DoubleOperand3.MantissaLow = DoubleQuotient.LowPart;
                DoubleOperand3.MantissaHigh = DoubleQuotient.HighPart;

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

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

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

                DoubleOperand3.Infinity = FALSE;
                DoubleOperand3.Nan = FALSE;
                return KiNormalizeDouble(&ContextBlock,
                                         &DoubleOperand3,
                                         DoubleDividend.LowPart | DoubleDividend.HighPart);

            } else {
                break;
            }

            //
            // Floating square root.
            //

        case FLOAT_SQUARE_ROOT:
            if (Format == FORMAT_SINGLE) {

                //
                // If the operand is plus infinity, then the result is
                // plus infinity, or if the operand is plus or minus
                // zero, then the result is plus or minus zero.
                //

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

                //
                // If the operand is negative, then the operation is
                // invalid.
                //

                if (SingleOperand1.Sign != 0) {
                    return KiInvalidOperationSingle(&ContextBlock,
                                                    FALSE,
                                                    &SingleOperand1,
                                                    &SingleOperand1);
                }

                //
                // The only case remaining that could cause an exception
                // is a denomalized source value. The square root of a
                // denormalized value is computed by:
                //
                //   1. Converting the value to a normalized value with
                //      an exponent equal to the denormalization shift count
                //      plus the bias of the exponent plus one.
                //
                //   2. Computing the square root of the value and unpacking
                //      the result.
                //
                //   3. Converting the shift count back to a normalization
                //      shift count.
                //
                //   4. Rounding and packing the resultant value.
                //
                // N.B. The square root of all denormalized number is a
                //      normalized number.
                //

                SingleOperand1.Exponent = (SINGLE_EXPONENT_BIAS + 1 +
                                            SingleOperand1.Exponent) << 23;

                SingleValue = (SingleOperand1.Mantissa & ~(1 << 25)) >> 2;
                SingleValue |= SingleOperand1.Exponent;
                StickyBits = KiSquareRootSingle(&SingleValue);
                SingleOperand1.Exponent =  (SingleValue >> 23) -
                                            ((SINGLE_EXPONENT_BIAS + 1) / 2);

                SingleOperand1.Mantissa = ((SingleValue &
                                            0x7fffff) | 0x800000) << 2;

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

            } else if (Format == FORMAT_DOUBLE) {

                //
                // If the operand is plus infinity, then the result is
                // plus infinity, or if the operand is plus or minus
                // zero, then the result is plus or minus zero.
                //

                if (((DoubleOperand1.Sign == 0) &&
                   (DoubleOperand1.Infinity != FALSE)) ||
                   (DoubleOperand1.MantissaHigh == 0)) {
                    return KiNormalizeDouble(&ContextBlock,
                                             &DoubleOperand1,
                                             0);
                }

                //
                // If the operand is negative, then the operation is
                // invalid.
                //

                if (DoubleOperand1.Sign != 0) {
                    return KiInvalidOperationDouble(&ContextBlock,
                                                    FALSE,
                                                    &DoubleOperand1,
                                                    &DoubleOperand1);
                }

                //
                // The only case remaining that could cause an exception
                // is a denomalized source value. The square root of a
                // denormalized value is computed by:
                //
                //   1. Converting the value to a normalized value with
                //      an exponent equal to the denormalization shift count
                //      plus the bias of the exponent plus one.
                //
                //   2. Computing the square root of the value and unpacking
                //      the result.
                //
                //   3. Converting the shift count back to a normalization
                //      shift count.
                //
                //   4. Rounding and packing the resultant value.
                //
                // N.B. The square root of all denormalized numbers is a
                //      normalized number.
                //

                DoubleOperand1.Exponent = (DOUBLE_EXPONENT_BIAS + 1 +
                                            DoubleOperand1.Exponent) << 20;

                DoubleValue.HighPart = (DoubleOperand1.MantissaHigh & ~(1 << 22)) >> 2;
                DoubleValue.LowPart = (DoubleOperand1.MantissaHigh << 30) |
                                            (DoubleOperand1.MantissaLow >> 2);

                DoubleValue.HighPart |= DoubleOperand1.Exponent;
                StickyBits = KiSquareRootDouble(&DoubleValue);
                DoubleOperand1.Exponent =  (DoubleValue.HighPart >> 20) -
                                            ((DOUBLE_EXPONENT_BIAS + 1) / 2);

                DoubleOperand1.MantissaLow = DoubleValue.LowPart << 2;
                DoubleOperand1.MantissaHigh = ((DoubleValue.HighPart &
                                            0xfffff) | 0x100000) << 2;

⌨️ 快捷键说明

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