Beispiel #1
0
/* reduce trigonometric function argument using 128-bit precision 
   M_PI approximation */
static Bit64u argument_reduction_kernel(Bit64u aSig0, int Exp, Bit64u *zSig0, Bit64u *zSig1)
{
    Bit64u term0, term1, term2;
    Bit64u aSig1 = 0;

    shortShift128Left(aSig1, aSig0, Exp, &aSig1, &aSig0);
    Bit64u q = estimateDiv128To64(aSig1, aSig0, FLOAT_PI_HI);
    mul128By64To192(FLOAT_PI_HI, FLOAT_PI_LO, q, &term0, &term1, &term2);
    sub128(aSig1, aSig0, term0, term1, zSig1, zSig0);
    while ((Bit64s)(*zSig1) < 0) {
        --q;
        add192(*zSig1, *zSig0, term2, 0, FLOAT_PI_HI, FLOAT_PI_LO, zSig1, zSig0, &term2);
    }
    *zSig1 = term2;
    return q;
}
Beispiel #2
0
/* reduce trigonometric function argument using 128-bit precision
   M_PI approximation */
static UINT64 argument_reduction_kernel(UINT64 aSig0, int Exp, UINT64 *zSig0, UINT64 *zSig1)
{
	UINT64 term0, term1, term2;
	UINT64 aSig1 = 0;

	shortShift128Left(aSig1, aSig0, Exp, &aSig1, &aSig0);
	UINT64 q = estimateDiv128To64(aSig1, aSig0, FLOAT_PI_HI);
	mul128By64To192(FLOAT_PI_HI, FLOAT_PI_LO, q, &term0, &term1, &term2);
	sub128(aSig1, aSig0, term0, term1, zSig1, zSig0);
	while ((INT64)(*zSig1) < 0) {
		--q;
		add192(*zSig1, *zSig0, term2, 0, FLOAT_PI_HI, FLOAT_PI_LO, zSig1, zSig0, &term2);
	}
	*zSig1 = term2;
	return q;
}
Beispiel #3
0
static int multiply( const ELD *op1, const ELD *op2, ELD *res )
/**************************************************************
    multiply u96 by u96 into u96
    normalize and round result
*/
{
    uint_64 x1;
    u192 r1;
    long exp;

    exp = (long)(op1->e & 0x7fff) + (long)(op2->e & 0x7fff) - EXPONENT_BIAS + 1;
    r1.m64[0] = (uint_64)(op1->m32[0]) * (uint_64)(op2->m32[0]);
    r1.m64[1] = (uint_64)(op1->m32[1]) * (uint_64)(op2->m32[1]);
    r1.m64[2] = (uint_64)(op1->m32[2]) * (uint_64)(op2->m32[2]);
    x1 = (uint_64)(op1->m32[1]) * (uint_64)(op2->m32[0]);
    add192(&r1, x1, 1);
    x1 = (uint_64)(op1->m32[0]) * (uint_64)(op2->m32[1]);
    add192(&r1, x1, 1);
    x1 = (uint_64)(op1->m32[0]) * (uint_64)(op2->m32[2]);
    add192(&r1, x1, 2);
    x1 = (uint_64)(op1->m32[2]) * (uint_64)(op2->m32[0]);
    add192(&r1, x1, 2);
    x1 = (uint_64)(op1->m32[1]) * (uint_64)(op2->m32[2]);
    add192(&r1, x1, 3);
    x1 = (uint_64)(op1->m32[2]) * (uint_64)(op2->m32[1]);
    add192(&r1, x1, 3);
    exp += normalize(&r1);
    // round result
    if( r1.m32[2] & 0x80000000U ) {
        if( r1.m32[5] == 0xffffffffU && r1.m32[4] == 0xffffffffU && r1.m32[3] == 0xffffffffU ) {
            r1.m32[3] = 0;
            r1.m32[4] = 0;
            r1.m32[5] = 0x80000000U;
            exp++;
        } else {
            x1 = 1L;
            add192(&r1, x1, 3);
        }
    }
    res->m32[0] = r1.m32[3];
    res->m32[1] = r1.m32[4];
    res->m32[2] = r1.m32[5];
    res->e = exp;
    return 0;
}