예제 #1
0
def trunc(x):
    if type(x) is types.sfix:
        return AdvInteger.Oblivious_Trunc(x.v, x.k, x.f, x.kappa)
    elif type(x) is types.sfloat:
        v, p, z, s = floatingpoint.FLRound(x, 0)
        return types.sfloat(v, p, z, s, x.err)
    return x
예제 #2
0
def FLRound(x, mode):
    """ Rounding with floating point output.
    *mode*: 0 -> floor, 1 -> ceil, -1 > trunc """
    v1, p1, z1, s1, l, k = x.v, x.p, x.z, x.s, x.vlen, x.plen
    a = types.sint()
    AdvInteger.LTZ(a, p1, k, x.kappa)
    b = p1.less_than(-l + 1, k, x.kappa)
    v2, inv_2pow_p1 = AdvInteger.Oblivious_Trunc(v1, l, -a * (1 - b) * x.p,
                                                 x.kappa, True)
    c = AdvInteger.EQZ(v2, l, x.kappa)
    if mode == -1:
        away_from_zero = 0
        mode = x.s
    else:
        away_from_zero = mode + s1 - 2 * mode * s1
    v = v1 - v2 + (1 - c) * inv_2pow_p1 * away_from_zero
    d = v.equal(AdvInteger.two_power(l), l + 1, x.kappa)
    v = d * AdvInteger.two_power(l - 1) + (1 - d) * v
    v = a * ((1 - b) * v +
             b * away_from_zero * AdvInteger.two_power(l - 1)) + (1 - a) * v1
    s = (1 - b * mode) * s1
    z = AdvInteger.or_op(AdvInteger.EQZ(v, l, x.kappa), z1)
    v = v * (1 - z)
    p = ((p1 + d * a) * (1 - b) + b * away_from_zero * (1 - l)) * (1 - z)
    return v, p, z, s