📄 float.c
字号:
// bits and are used later in the rounding operation.
//
ExponentDifference =
DoubleOperand1.Exponent - DoubleOperand2.Exponent;
if (ExponentDifference > 55) {
ExponentDifference = 55;
}
if (ExponentDifference >= 32) {
ExponentDifference -= 32;
StickyBits = (DoubleOperand2.MantissaLow) |
(DoubleOperand2.MantissaHigh & ((1 << ExponentDifference) - 1));
DoubleMantissaLow =
DoubleOperand2.MantissaHigh >> ExponentDifference;
DoubleMantissaHigh = 0;
} else if (ExponentDifference > 0) {
StickyBits =
DoubleOperand2.MantissaLow & ((1 << ExponentDifference) - 1);
DoubleMantissaLow =
(DoubleOperand2.MantissaLow >> ExponentDifference) |
(DoubleOperand2.MantissaHigh << (32 - ExponentDifference));
DoubleMantissaHigh =
DoubleOperand2.MantissaHigh >> ExponentDifference;
} else {
StickyBits = 0;
DoubleMantissaLow = DoubleOperand2.MantissaLow;
DoubleMantissaHigh = DoubleOperand2.MantissaHigh;
}
//
// If the operands both have the same sign, then perform the
// operation by adding the values together. Otherwise, perform
// the operation by subtracting the second operand from the
// first operand.
//
if ((DoubleOperand1.Sign ^ DoubleOperand2.Sign) == 0) {
DoubleOperand1.MantissaLow += DoubleMantissaLow;
DoubleOperand1.MantissaHigh += DoubleMantissaHigh;
if (DoubleOperand1.MantissaLow < DoubleMantissaLow) {
DoubleOperand1.MantissaHigh += 1;
}
} else {
if ((DoubleOperand1.Infinity != FALSE) &&
(DoubleOperand2.Infinity != FALSE)) {
return KiInvalidOperationDouble(&ContextBlock,
FALSE,
&DoubleOperand1,
&DoubleOperand2);
} else if (DoubleOperand1.Infinity == FALSE) {
if (StickyBits != 0) {
if (DoubleOperand1.MantissaLow < 1) {
DoubleOperand1.MantissaHigh -= 1;
}
DoubleOperand1.MantissaLow -= 1;
}
if (DoubleOperand1.MantissaLow < DoubleMantissaLow) {
DoubleOperand1.MantissaHigh -= 1;
}
DoubleOperand1.MantissaLow -= DoubleMantissaLow;
DoubleOperand1.MantissaHigh -= DoubleMantissaHigh;
if (DoubleOperand1.MantissaHigh < 0) {
DoubleOperand1.MantissaLow = ~DoubleOperand1.MantissaLow + 1;
DoubleOperand1.MantissaHigh = -DoubleOperand1.MantissaHigh;
if (DoubleOperand1.MantissaLow != 0) {
DoubleOperand1.MantissaHigh -= 1;
}
DoubleOperand1.Sign ^= 0x1;
}
// force to positive if result equal to zero
if ((DoubleOperand1.MantissaLow | DoubleOperand1.MantissaHigh) == 0)
DoubleOperand1.Sign = 0x0;
}
}
if (Function == FLOAT_NMADD || Function == FLOAT_NMSUB)
DoubleOperand1.Sign ^= 0x1;
//
// Normalize and store the result value.
//
return KiNormalizeDouble(&ContextBlock,
&DoubleOperand1,
StickyBits);
}
}
#endif
switch (Function) {
//
// Floating subtract operation.
//
// Floating subtract is accomplished by complementing the sign
// of the second operand and then performing an add operation.
//
case FLOAT_SUBTRACT:
Negation = 0x1;
//
// Floating add operation.
//
// Floating add is accomplished using signed magnitude addition.
//
// The exponent difference is calculated and the smaller number
// is right shifted by the specified amount, but no more than
// the width of the operand values (i.e., 26 for single and 55
// for double). The shifted out value is saved for rounding.
//
// If the signs of the two operands are the same, then they
// are added together after having performed the alignment
// shift.
//
// If the signs of the two operands are different, then the
// sign of the result is the sign of the larger operand and
// the smaller operand is subtracted from the larger operand.
// In order to avoid making a double level test (i.e., one on
// the exponents, and one on the mantissas if the exponents
// are equal), it is posible that the result of the subtract
// could be negative (if the exponents are equal). If this
// occurs, then the result sign and mantissa are complemented
// to obtain the correct result.
//
case FLOAT_ADD:
if (Format == FORMAT_SINGLE) {
//
// Complement the sign of the second operand if the operation
// is subtraction.
//
SingleOperand2.Sign ^= Negation;
//
// Reorder then operands according to their exponent value.
//
if (SingleOperand2.Exponent > SingleOperand1.Exponent) {
SingleOperand3 = SingleOperand2;
SingleOperand2 = SingleOperand1;
SingleOperand1 = SingleOperand3;
}
//
// Compute the exponent difference and shift the smaller
// mantissa right by the difference value or 26 which ever
// is smaller. The bits shifted out are termed the sticky
// bits and are used later in the rounding operation.
//
ExponentDifference =
SingleOperand1.Exponent - SingleOperand2.Exponent;
if (ExponentDifference > 26) {
ExponentDifference = 26;
}
StickyBits =
SingleOperand2.Mantissa & ((1 << ExponentDifference) - 1);
SingleMantissa = SingleOperand2.Mantissa >> ExponentDifference;
//
// If the operands both have the same sign, then perform the
// operation by adding the values together. Otherwise, perform
// the operation by subtracting the second operand from the
// first operand.
//
if ((SingleOperand1.Sign ^ SingleOperand2.Sign) == 0) {
SingleOperand1.Mantissa += SingleMantissa;
} else {
if ((SingleOperand1.Infinity != FALSE) &&
(SingleOperand2.Infinity != FALSE)) {
return KiInvalidOperationSingle(&ContextBlock,
FALSE,
&SingleOperand1,
&SingleOperand2);
} else if (SingleOperand1.Infinity == FALSE) {
if (StickyBits != 0) {
SingleOperand1.Mantissa -= 1;
}
SingleOperand1.Mantissa -= SingleMantissa;
if (SingleOperand1.Mantissa < 0) {
SingleOperand1.Mantissa = -SingleOperand1.Mantissa;
SingleOperand1.Sign ^= 0x1;
}
}
}
//
// Normalize and store the result value.
//
return KiNormalizeSingle(&ContextBlock,
&SingleOperand1,
StickyBits);
} else if (Format == FORMAT_DOUBLE) {
//
// Complement the sign of the second operand if the operation
// is subtraction.
//
DoubleOperand2.Sign ^= Negation;
//
// Reorder then operands according to their exponent value.
//
if (DoubleOperand2.Exponent > DoubleOperand1.Exponent) {
DoubleOperand3 = DoubleOperand2;
DoubleOperand2 = DoubleOperand1;
DoubleOperand1 = DoubleOperand3;
}
//
// Compute the exponent difference and shift the smaller
// mantissa right by the difference value or 55 which ever
// is smaller. The bits shifted out are termed the sticky
// bits and are used later in the rounding operation.
//
ExponentDifference =
DoubleOperand1.Exponent - DoubleOperand2.Exponent;
if (ExponentDifference > 55) {
ExponentDifference = 55;
}
if (ExponentDifference >= 32) {
ExponentDifference -= 32;
StickyBits = (DoubleOperand2.MantissaLow) |
(DoubleOperand2.MantissaHigh & ((1 << ExponentDifference) - 1));
DoubleMantissaLow =
DoubleOperand2.MantissaHigh >> ExponentDifference;
DoubleMantissaHigh = 0;
} else if (ExponentDifference > 0) {
StickyBits =
DoubleOperand2.MantissaLow & ((1 << ExponentDifference) - 1);
DoubleMantissaLow =
(DoubleOperand2.MantissaLow >> ExponentDifference) |
(DoubleOperand2.MantissaHigh << (32 - ExponentDifference));
DoubleMantissaHigh =
DoubleOperand2.MantissaHigh >> ExponentDifference;
} else {
StickyBits = 0;
DoubleMantissaLow = DoubleOperand2.MantissaLow;
DoubleMantissaHigh = DoubleOperand2.MantissaHigh;
}
//
// If the operands both have the same sign, then perform the
// operation by adding the values together. Otherwise, perform
// the operation by subtracting the second operand from the
// first operand.
//
if ((DoubleOperand1.Sign ^ DoubleOperand2.Sign) == 0) {
DoubleOperand1.MantissaLow += DoubleMantissaLow;
DoubleOperand1.MantissaHigh += DoubleMantissaHigh;
if (DoubleOperand1.MantissaLow < DoubleMantissaLow) {
DoubleOperand1.MantissaHigh += 1;
}
} else {
if ((DoubleOperand1.Infinity != FALSE) &&
(DoubleOperand2.Infinity != FALSE)) {
return KiInvalidOperationDouble(&ContextBlock,
FALSE,
&DoubleOperand1,
&DoubleOperand2);
} else if (DoubleOperand1.Infinity == FALSE) {
if (StickyBits != 0) {
if (DoubleOperand1.MantissaLow < 1) {
DoubleOperand1.MantissaHigh -= 1;
}
DoubleOperand1.MantissaLow -= 1;
}
if (DoubleOperand1.MantissaLow < DoubleMantissaLow) {
DoubleOperand1.MantissaHigh -= 1;
}
DoubleOperand1.MantissaLow -= DoubleMantissaLow;
DoubleOperand1.MantissaHigh -= DoubleMantissaHigh;
if (DoubleOperand1.MantissaHigh < 0) {
DoubleOperand1.MantissaLow = ~DoubleOperand1.MantissaLow + 1;
DoubleOperand1.MantissaHigh = -DoubleOperand1.MantissaHigh;
if (DoubleOperand1.MantissaLow != 0) {
DoubleOperand1.MantissaHigh -= 1;
}
DoubleOperand1.Sign ^= 0x1;
}
// force to positive if result equal to zero
if ((DoubleOperand1.MantissaLow | DoubleOperand1.MantissaHigh) == 0)
DoubleOperand1.Sign = 0x0;
}
}
//
// Normalize and store the result value.
//
return KiNormalizeDouble(&ContextBlock,
&DoubleOperand1,
StickyBits);
} else {
break;
}
//
// Floating multiply operation.
//
// Floating multiply is accomplished using unsigned multiplies
// of the mantissa values, and adding the parital results together
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -