📄 float.c
字号:
} 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 + -