📄 float.c
字号:
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; } } } // // 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 // 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)) ||
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -