def accuracy_bound_search_ub(ubp, lbp, test_fun, mid_p, idx):
    for i in range(0, 2000):
        mid_i = float(fadd(lbp, fsub(ubp, lbp) / 2.0))
        mid_p[idx] = mid_i
        res = test_fun(*mid_p)
        if isfloat(res.val):
            ubp = mid_i
        else:
            lbp = mid_i
        dis_lu = bf.getUlpError(lbp, ubp)
        # print dis_lu
        if dis_lu <= 2:
            break
    return ubp
def binary_find_bound(sinp, bound, inp, test_fun, idx):
    mid_p = list(inp)
    # print "binary_find_bound"
    # print sinp
    # print bound
    lbp = bound[0]
    ubp = sinp
    max_step = bf.getUlpError(sinp, bound[0])
    ini_step = np.min([40, max_step])
    st_p = sinp + 0
    temp_p = sinp
    for i in range(0, 2000):
        # print "hello"
        # print sinp
        # print st_p
        # print ini_step
        # print float(max_step)
        # print bound[0]
        if ini_step >= max_step:
            lbp = accuracy_bound_search_lb(temp_p, bound[0], test_fun,
                                           list(inp), idx)
            break
        st_p = bf.get_next_point(sinp, ini_step, -1)
        mid_p[idx] = st_p
        if st_p < bound[0]:
            lbp = bound[0]
            break
        res = test_fun(*mid_p)
        # print res.val
        if not isfloat(res.val):
            ini_step = ini_step * 2.0
        else:
            lbp = accuracy_bound_search_lb(temp_p, st_p, test_fun, list(inp),
                                           idx)
            break
        temp_p = st_p
        # dis_lu = bf.getUlpError(lbp,ubp)
        # if dis_lu <= 2:
        #     break
    fl_lbp = lbp
    lbp = sinp
    ubp = bound[1]
    max_step = bf.getUlpError(sinp, bound[1])
    ini_step = np.min([40, max_step])
    st_p = sinp + 0
    mid_p = list(inp)
    temp_p = sinp
    for i in range(0, 2000):
        if ini_step >= max_step:
            ubp = accuracy_bound_search_lb(temp_p, bound[1], test_fun,
                                           list(inp), idx)
            break
        st_p = bf.get_next_point(sinp, ini_step, 1)
        mid_p[idx] = st_p
        if st_p > bound[1]:
            ubp = bound[1]
            break
        res = test_fun(*mid_p)
        if not isfloat(res.val):
            ini_step = ini_step * 2.0
        else:
            ubp = accuracy_bound_search_ub(temp_p, st_p, test_fun, list(inp),
                                           idx)
            break
        temp_p = st_p
        # mid_i = float(fadd(lbp, fsub(ubp, lbp) / 2.0))
        # mid_p[idx] = mid_i
        # res = test_fun(*mid_p)
        # if isfloat(res.val):
        #     ubp = mid_i
        # else:
        #     lbp = mid_i
        # dis_lu = bf.getUlpError(lbp, ubp)
        # if dis_lu <= 2:
        #     break
    fl_ubp = ubp
    return [fl_lbp, fl_ubp]