📄 float.c
字号:
((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; DoubleOperand1.MantissaHigh |= (DoubleValue.LowPart >> 30); return KiNormalizeDouble(&ContextBlock, &DoubleOperand1, StickyBits); } else { break; } // // Floating absolute operation. // // Floating absolute is accomplished by clearing the sign // of the floating value. // case FLOAT_ABSOLUTE: if (Format == FORMAT_SINGLE) { // // Clear the sign, normalize the result, and store in the // destination register. // SingleOperand1.Sign = 0; return KiNormalizeSingle(&ContextBlock, &SingleOperand1, 0); } else if (Format == FORMAT_DOUBLE) { // // Clear the sign, normalize the result, and store in the // destination register. //
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -