示例#1
0
def test_two_sum_simple():
    with decimal.localcontext(decimal.Context(prec=40)):
        i, f = 65536, 3.637978807091714e-12
        a = Decimal(i) + Decimal(f)
        s, r = two_sum(i, f)
        b = Decimal(s) + Decimal(r)
        assert (abs(a - b) * u.day).to(u.ns) < 1 * u.ns
示例#2
0
def day_frac(val1, val2, factor=None, divisor=None):
    """Return the sum of ``val1`` and ``val2`` as two float64s.

    The returned floats are an integer part and the fractional remainder,
    with the latter guaranteed to be within -0.5 and 0.5 (inclusive on
    either side, as the integer is rounded to even).

    The arithmetic is all done with exact floating point operations so no
    precision is lost to rounding error.  It is assumed the sum is less
    than about 1e16, otherwise the remainder will be greater than 1.0.

    Parameters
    ----------
    val1, val2 : array of float
        Values to be summed.
    factor : float, optional
        If given, multiply the sum by it.
    divisor : float, optional
        If given, divide the sum by it.

    Returns
    -------
    day, frac : float64
        Integer and fractional part of val1 + val2.
    """
    # Note that the version of astropy >=3.2;
    # See https://github.com/astropy/astropy/pull/8763
    # TODO: remove when we only support astropy >=3.2.
    #
    # Add val1 and val2 exactly, returning the result as two float64s.
    # The first is the approximate sum (with some floating point error)
    # and the second is the error of the float64 sum.
    sum12, err12 = two_sum(val1, val2)

    if factor is not None:
        sum12, carry = two_product(sum12, factor)
        carry += err12 * factor
        sum12, err12 = two_sum(sum12, carry)

    if divisor is not None:
        q1 = sum12 / divisor
        p1, p2 = two_product(q1, divisor)
        d1, d2 = two_sum(sum12, -p1)
        d2 += err12
        d2 -= p2
        q2 = (d1 + d2) / divisor  # 3-part float fine here; nothing can be lost
        sum12, err12 = two_sum(q1, q2)

    # get integer fraction
    day = np.around(sum12)
    extra, frac = two_sum(sum12, -day)
    frac += extra + err12
    # This part was missed in astropy...
    excess = np.around(frac)
    day += excess
    extra, frac = two_sum(sum12, -day)
    frac += extra + err12
    return day, frac
示例#3
0
def test_two_sum_size(f1, f2):
    r1, r2 = two_sum(f1, f2)
    assert (abs(r1) > abs(r2) / np.finfo(float).eps or r1 == r2 == 0
            or not np.isfinite(f1 + f2))
示例#4
0
def test_two_sum_symmetric(f1, f2):
    np.testing.assert_equal(two_sum(f1, f2), two_sum(f2, f1))
示例#5
0
def test_two_sum(i, f):
    with decimal.localcontext(decimal.Context(prec=40)):
        a = Decimal(i) + Decimal(f)
        s, r = two_sum(i, f)
        b = Decimal(s) + Decimal(r)
        assert_almost_equal(a, b, atol=Decimal(tiny), rtol=Decimal(0))