コード例 #1
0
ファイル: CodeInterval.cpp プロジェクト: Recmo/EntropyCoder
bool CodeInterval::update(const Interval& symbol) throw(not_normalized, invalid_symbol)
{
	if(!is_normalized()) {
		throw not_normalized("Interval must be normalized before update.");
	}
	if(symbol.range < 3 || symbol.base + symbol.range < symbol.base) {
		throw invalid_symbol("Invalid symbol interval.");
	}
	
	// Calculate the new base
	uint64 h, l;
	std::tie(h, l) = mul128(symbol.base, range);
	std::tie(h, l) = add128(h, l, symbol.base);
	const uint64 t = h + (l > 0 ? 1 : 0);
	base += t;
	
	// Calculate the new range
	std::tie(h, l) = mul128(symbol.base + symbol.range, range);
	std::tie(h, l) = add128(h, l, symbol.base + symbol.range);
	std::tie(h, l) = add128(h, l, range);
	std::tie(h, l) = add128(h, l, 1);
	range = h - t - 1;
	
	// Return carry
	return base < t;
}
コード例 #2
0
ファイル: pr24670.c プロジェクト: 0day-ci/gcc
void
float128_rem ()
{
  signed int expDiff;
  long long int aSig1;
  long long int sigMean1;
  if (-64 < expDiff)
    shift128Right (-expDiff, &aSig1);
  add128 (&sigMean1);
}
コード例 #3
0
ファイル: coder.cpp プロジェクト: vadimkantorov/urfu
/*
 * When decoding, this routine is called to figure out which symbol
 * is presently waiting to be decoded.  This routine expects to get
 * the current model scale in the s->scale parameter, and it returns
 * a count that corresponds to the present floating point code:
 *
 *  code = count / s->scale
 */
unsigned long long get_current_count( SYMBOL *s )
{
    unsigned long long range = (unsigned long long) ( high - low ) + 1;
    unsigned long long z = (unsigned long long)(code - low) + 1;
    qofint128 one = {0, 1, 1, 0};
    qofint128 a = mult128(z, s->scale);
    qofint128 b = add128(a, one);
    qofint128 c = div128(b, range);
    return c.lo;
}
コード例 #4
0
ファイル: fprem.cpp プロジェクト: ralvaradoc/libsf
/* executes single exponent reduction cycle */
static Bit64u remainder_kernel(Bit64u aSig0, Bit64u bSig, int expDiff, Bit64u *zSig0, Bit64u *zSig1)
{
    Bit64u term0, term1;
    Bit64u aSig1 = 0;

    shortShift128Left(aSig1, aSig0, expDiff, &aSig1, &aSig0);
    Bit64u q = estimateDiv128To64(aSig1, aSig0, bSig);
    mul64To128(bSig, q, &term0, &term1);
    sub128(aSig1, aSig0, term0, term1, zSig1, zSig0);
    while ((Bit64s)(*zSig1) < 0) {
        --q;
        add128(*zSig1, *zSig0, 0, bSig, zSig1, zSig0);
    }
    return q;
}
コード例 #5
0
ファイル: Definitions.cpp プロジェクト: SChernykh/Amicable
void atoi128(const char* s, number &numlo, number &numhi)
{
	numlo = 0;
	numhi = 0;
	for (;;)
	{
		const unsigned char d = static_cast<unsigned char>(*(s++) - '0');
		if (d > 9)
		{
			break;
		}

		number k[2];
		k[0] = _umul128(numlo, 10, &k[1]);
		k[1] += numhi * 10;
		add128(k[0], k[1], d, 0, k, k + 1);
		numlo = k[0];
		numhi = k[1];
	}
}
コード例 #6
0
ファイル: gnc-numeric.c プロジェクト: rratliff/gnucash
gnc_numeric
gnc_numeric_add(gnc_numeric a, gnc_numeric b,
                gint64 denom, gint how)
{
    gnc_numeric sum;

    if (gnc_numeric_check(a) || gnc_numeric_check(b))
    {
        return gnc_numeric_error(GNC_ERROR_ARG);
    }

    if ((denom == GNC_DENOM_AUTO) &&
            (how & GNC_NUMERIC_DENOM_MASK) == GNC_HOW_DENOM_FIXED)
    {
        if (a.denom == b.denom)
        {
            denom = a.denom;
        }
        else if (b.num == 0)
        {
            denom = a.denom;
            b.denom = a.denom;
        }
        else if (a.num == 0)
        {
            denom = b.denom;
            a.denom = b.denom;
        }
        else
        {
            return gnc_numeric_error(GNC_ERROR_DENOM_DIFF);
        }
    }

    if (a.denom < 0)
    {
        a.num *= -a.denom;  /* BUG: overflow not handled.  */
        a.denom = 1;
    }

    if (b.denom < 0)
    {
        b.num *= -b.denom;  /* BUG: overflow not handled.  */
        b.denom = 1;
    }

    /* Get an exact answer.. same denominator is the common case. */
    if (a.denom == b.denom)
    {
        sum.num = a.num + b.num;  /* BUG: overflow not handled.  */
        sum.denom = a.denom;
    }
    else
    {
        /* We want to do this:
         *    sum.num = a.num*b.denom + b.num*a.denom;
         *    sum.denom = a.denom*b.denom;
         * but the multiply could overflow.
         * Computing the LCD minimizes likelihood of overflow
         */
        gint64 lcd;
        qofint128 ca, cb, cab;
        lcd = gnc_numeric_lcd(a, b);
        if (GNC_ERROR_ARG == lcd)
        {
            return gnc_numeric_error(GNC_ERROR_OVERFLOW);
        }
        ca = mult128 (a.num, lcd / a.denom);
        if (ca.isbig) return gnc_numeric_error(GNC_ERROR_OVERFLOW);

        cb = mult128 (b.num, lcd / b.denom);
        if (cb.isbig) return gnc_numeric_error(GNC_ERROR_OVERFLOW);

        cab = add128 (ca, cb);
        if (cab.isbig) return gnc_numeric_error(GNC_ERROR_OVERFLOW);

        sum.num   = cab.lo;
        if (cab.isneg) sum.num = -sum.num;
        sum.denom = lcd;
    }

    if ((denom == GNC_DENOM_AUTO) &&
            ((how & GNC_NUMERIC_DENOM_MASK) == GNC_HOW_DENOM_LCD))
    {
        denom = gnc_numeric_lcd(a, b);
        how   = how & GNC_NUMERIC_RND_MASK;
    }

    return gnc_numeric_convert(sum, denom, how);
}
コード例 #7
0
static void neg128 (uint64_t *plow, uint64_t *phigh)
{
    *plow = ~*plow;
    *phigh = ~*phigh;
    add128(plow, phigh, 1, 0);
}