Python娱乐,不用一个数计算四则运算

141 阅读12分钟
D_BIT_ZERO = '0'
D_BIT_ONE = '1'

D_TRUE = D_BIT_ONE
D_FALSE = D_BIT_ZERO

D_TEN_ONE =   '1'
D_TEN_TWO =   '2'
D_TEN_THREE = '3'
D_TEN_FOUR =  '4'
D_TEN_FIVE =  '5'
D_TEN_SIX =   '6'
D_TEN_SEVEN = '7'
D_TEN_EIGHT = '8'
D_TEN_NINE =  '9'
D_TEN_ZERO =  '0'

D_ONE   = '00000001'
D_TWO   = '00000010'
D_THREE = '00000011'
D_FOUR  = '00000100'
D_FIVE  = '00000101'
D_SIX   = '00000110'
D_SEVEN = '00000111'
D_EIGHT = '00001000'
D_NINE  = '00001001'
D_ZERO  = '00000000'
D_TEN   = '00001010'

D_LENGTH = D_EIGHT

D_BLANK = ''


def d_bit_is(a, b):
    """位操作-是"""
    if a == D_BIT_ZERO:
        if b == D_BIT_ZERO:
            return D_TRUE
        if b == D_BIT_ONE:
            return D_FALSE
    if a == D_BIT_ONE:
        if b == D_BIT_ZERO:
            return D_FALSE
        if b == D_BIT_ONE:
            return D_TRUE


def d_bit_isnt(a, b):
    """位操作-非"""
    return d_bit_not(d_bit_is(a, b))


def d_bit_and(a, b):
    """位操作-与"""
    if a == D_BIT_ZERO:
        if b == D_BIT_ZERO:
            return D_FALSE
        if b == D_BIT_ONE:
            return D_FALSE
    if a == D_BIT_ONE:
        if b == D_BIT_ZERO:
            return D_FALSE
        if b == D_BIT_ONE:
            return D_TRUE


def d_bit_not(a):
    """位操作-取反"""
    if a == D_BIT_ZERO:
        return D_BIT_ONE
    if a == D_BIT_ONE:
        return D_BIT_ZERO


def d_bit_or(a, b):
    """位操作-或"""
    if a == D_BIT_ZERO:
        if b == D_BIT_ZERO:
            return D_FALSE
        if b == D_BIT_ONE:
            return D_TRUE
    if a == D_BIT_ONE:
        if b == D_BIT_ZERO:
            return D_TRUE
        if b == D_BIT_ONE:
            return D_TRUE


def d_bit_xor(a, b):
    """
    位操作-异或
    简单的说,位的异或结果就是相同为0,不同为1
    """
    return d_bit_or(d_bit_and(d_bit_not(a), b), d_bit_and(a, d_bit_not(b)))


def d_xor(m, n):
    res = ''
    ml = list(m)
    nl = list(n)
    while ml and nl:
        mlp = ml.pop()
        nlp = nl.pop()
        xor = d_bit_xor(mlp, nlp)
        res = xor + res
    return res


def d_is(m, n):
    """
    判断两个数相等
    数的表示和值是满射,直接复用字符串的比较方法,提升效率
    下面段1使用栈的方式更接近本质一点
    段2无法避开index的数值运算
    段3是异或串联的思路,只要有一位是不同的,串联结果即不同
    段4的并行迭代貌似不是扁平了,暂时不讨论了
    """
    if m == n:
        return D_TRUE
    else:
        return D_FALSE

    # 段1
    # res = D_TRUE
    # ml = list(m)
    # nl = list(n)
    # while ml:
    #     mlp = ml.pop()
    #     nlp = nl.pop()
    #     if d_bit_isnt(mlp, nlp) == D_TRUE:
    #         res = D_FALSE
    #         break
    # return res

    # 段2
    # res = D_TRUE
    # i = D_ZERO
    # # i in range(d_len(num1))
    # while D_TRUE == D_TRUE:
    #     if d_not(d_bit_and(d_less_or_is(D_ZERO, i), d_less(i, d_len(num1)))) == D_TRUE:
    #         break
    #     # b1 = num1[i]
    #     b1 = d_index(num1, i)
    #     # b2 = num2[i]
    #     b2 = d_index(num2, i)
    #     if d_bit_isnt(b1, b2) == D_TRUE:
    #         res = D_FALSE
    #         break
    #     i = d_next(i)

    # 段3
    # xor = d_xor(num1, num2)
    # # 当且仅当xor各位同为0时两数相等
    # s_xor = d_serials_or(xor)
    # if s_xor == D_FALSE:
    #     return D_TRUE

    # 段4
    # for m, n in zip(num1, num2):
    #     if d_bit_is(m, n) == D_FALSE:
    #         return D_FALSE


def d_s_and(num):
    """
    串联与
    """
    res = D_TRUE
    for n in num:
        res = d_bit_and(res, n)
    return res


def d_serials_or(num):
    """
    串联或
    """
    res = D_FALSE
    for n in num:
        res = d_bit_or(res, n)
    return res


def d_next(num):
    """
    位操作-后继
    注意注释的代码,这里next调用了index,而index又调用了next,这是一个循环算法,导致栈溢出
    TODO 自增溢出问题
    """
    res = ''
    num_l = list(num)
    carry = D_TRUE
    while num_l:
        b = num_l.pop()
        if carry == D_TRUE:
            # 吞掉进位标识
            if d_bit_is(b, D_BIT_ZERO) == D_TRUE:
                carry = D_FALSE
            # 0变1,1变零(进位自旋)
            b = d_bit_not(b)
        res = b + res
    return res

    # 失败尝试1
    # res = d_xor(num, D_ONE)
    # return res

    # 失败尝试2
    # # index为-1即length-1
    # # res = num[-1]
    # res = d_index(num, d_prev(d_len(num)))
    # # 进位标识
    # b_carry = D_FALSE
    # # 如果最低位为1
    # if d_bit_is(res, D_BIT_ONE) == D_TRUE:
    #     # 结果最低位置0
    #     res = D_BIT_ZERO
    #     # 进位
    #     b_carry = D_BIT_ONE
    # # 如果最低位为0
    # if d_bit_is(res, D_BIT_ZERO) == D_TRUE:
    #     # 结果最低位置1
    #     res = D_BIT_ONE
    # # i in range(1, len(num))
    # i = D_ONE
    # while d_bit_and(d_less_or_is(D_ONE, i), d_less(i, d_len(num))) == D_TRUE:
    #     # 自右往左取第i位
    #     # index = -(i+1) 即 length-1-i
    #     index = d_minus(d_minus(d_len(num), i), D_ONE)
    #     # bi = num[-i - 1]  # -2,-3,...,-8
    #     bi = d_index(num, index)
    #     # 如果第i位为0,且前i-1位进位的情况
    #     if d_bit_and(d_bit_is(bi, D_BIT_ZERO), d_bit_is(b_carry, D_BIT_ONE)) == D_TRUE:
    #         # 本位置1
    #         bi = D_BIT_ONE
    #         # 进位标识置0
    #         b_carry = D_BIT_ZERO
    #         # 低位全置0 TODO
    #         res = d_zero(d_len(res))
    #     # 如果第i位为1,且前i-1位进位的情况
    #     if d_bit_and(d_bit_is(bi, D_BIT_ONE), d_bit_is(b_carry, D_BIT_ONE)) == D_TRUE:
    #         # 本位置0,继续进位
    #         bi = D_BIT_ZERO
    #     res = bi + res
    #     i = d_next(i)
    # # 溢出
    # if b_carry == D_TRUE:
    #     res = d_zero(d_len(res))
    # return res


def d_bit_less(a, b):
    """位操作-小于"""
    if d_bit_is(a, D_BIT_ONE) == D_TRUE:
        if d_bit_is(b, D_BIT_ZERO) == D_TRUE:
            return D_FALSE
    if d_bit_is(a, D_BIT_ZERO) == D_TRUE:
        if d_bit_is(b, D_BIT_ONE) == D_TRUE:
            return D_TRUE


def d_less_compare(m, n):
    res = D_FALSE
    ml = list(m)
    nl = list(n)
    # TODO and
    # TODO 对于等于的讨论
    while ml:
        mlp = ml.pop()
        nlp = nl.pop()
        if d_bit_less(mlp, nlp) == D_TRUE:
            res = D_TRUE
        if d_bit_less(nlp, mlp) == D_TRUE:
            res = D_FALSE
    # TODO 关于负数的特殊讨论
    return res


def d_less(m, n):
    if m == d_bound(d_len(m)):  # TODO
        m = d_zero(d_len(m))  # TODO
    # 先进行有效位数的比较提高效率
    m_len = d_len(d_cut_left_zeros(m))
    n_len = d_len(d_cut_left_zeros(n))
    m_len, n_len = d_alin(m_len, n_len)
    if d_less_compare(m_len, n_len) == D_TRUE:
        return D_TRUE
    return d_less_compare(m, n)


def d_less_or_is(num1, num2):
    """小于等于"""
    dp = d_less(num1, num2)
    di = d_is(num1, num2)
    return d_bit_or(dp, di)


def d_plus(m, n):
    """加法"""
    # 比较交换,保证左侧是大数
    if d_less(m, n) == D_TRUE:
        m, n = n, m
    res = m
    # 溢出标识
    of = D_FALSE
    zero = d_zero(d_len(m))
    count = zero
    while d_less(count, n) == D_TRUE:
        # 溢出之后,res会归零重新处理
        res = d_next(res)
        if d_bit_is(res, zero):
            of = D_TRUE
        # 即使溢出,也继续运算,方便后续处理
        count = d_next(count)
    return res, of


def d_zero(n=D_LENGTH):
    """返回n位的0"""
    # 8位直接返回常量
    if d_is(n, D_EIGHT) == D_TRUE:
        return D_ZERO
    # 其他位数直接拼接
    # TODO 关于异常输入的判断问题,何时抛异常,何时逻辑处理
    else:
        res = D_BLANK
        i = D_ZERO
        while D_TRUE == D_TRUE:
            if d_is(i, n) == D_TRUE:
                break
            # TODO +=
            res = res + D_BIT_ZERO
            i = d_next(i)
        return res


def d_bound(n):
    """返回n位的越界数"""
    return d_ones(n)


def d_one(n=D_LENGTH):
    """返回8位的1"""
    # TODO 校验方法调用
    if d_is(n, D_EIGHT) == D_TRUE:
        return D_ONE
    else:
        res = D_ONE
        i = D_ZERO
        # 循环 n-1 次
        while D_TRUE == D_TRUE:
            if d_is(i, n) == D_TRUE:
                break
            res = D_ZERO + res
            i = d_next(i)
        return res


def d_ones(n=D_LENGTH):
    """返回8位全1"""
    return d_not(d_zero(n))


def d_one_neg(n=D_LENGTH):
    """返回负1"""
    # TODO 校验方法调用
    return d_not(d_one(n))


def d_mul(m, n):
    """
    乘法
    效率:
    1.比较交换
    """
    if d_less(m, n):
        m, n = n, m
    res = m
    # 溢出标识
    of = D_FALSE
    # 乘法扩容问题
    i = d_next(d_zero(d_len(m)))
    while D_TRUE == D_TRUE:
        # jump = d_bit_not(d_less(i, n))
        if d_is(i, n) == D_TRUE:
            break
        res, off = d_plus(res, m)
        i = d_next(i)
        # 越界
        if off == D_TRUE:
            of = D_TRUE
    # TODO 溢出问题
    return res, of


def d_power(m, n):
    """幂"""
    res = m
    if d_is(n, d_zero(d_len(m))) == D_TRUE:
        return d_one(d_len(m))
    count = d_one()
    # 执行n-1次
    while D_TRUE == D_TRUE:
        if d_is(count, n) == D_TRUE:
            break
        res, _ = d_mul(res, m)
        count = d_next(count)
    return res


def d_not(num):
    """并列取反"""
    res = D_BLANK
    for n in num:
        res = res + d_bit_not(n)
    return res


def d_prev(num):
    """前一元素"""
    # one_neg = d_ones_neg()
    # res, _ = d_plus(num, one_neg)

    res = D_BLANK
    # 借位标识
    borrow = D_TRUE

    nl = list(num)
    while nl:
        b = nl.pop()
        if borrow == D_TRUE:
            if d_bit_is(b, D_BIT_ONE) == D_TRUE:
                # 共轭
                borrow = D_FALSE
            # 自旋
            b = d_bit_not(b)
        res = b + res
    return res
    #
    #
    # # i in range(0, d_len(num))
    # while d_bit_and(d_less_or_is(D_ZERO, i), d_less(i, d_len(num))) == D_TRUE:
    #     # 自右往左取第i位
    #     index = d_minus(d_minus(d_len(num), D_ONE), i)
    #     # bi = num[-(i + 1)]  # -1, -2,-3,...,-8
    #     bi = d_index(num, index)
    #     # 如果第i位为1,且前i-1位借位的情况
    #     if d_bit_and(d_bit_is(bi, D_BIT_ONE), borrow) == D_TRUE:
    #         # 本位置0,借位标识置0,后续位数均置1
    #         bi = D_BIT_ZERO
    #         borrow = D_FALSE
    #         res = d_ones(d_len(res))
    #     res = bi + res
    #     i = d_next(i)
    # # 溢出
    # if borrow == D_TRUE:
    #     res = d_zero(d_len(res))
    # return res


def d_minus(m, n):
    """减法"""
    res = m
    i = d_zero(d_len(m))
    # 执行n次
    while D_TRUE == D_TRUE:
        if d_is(i, n) == D_TRUE:
            break
        res = d_prev(res)
        i = d_next(i)
    # 对于结果为0的特殊处理(存在两个零的问题) TODO 待完善
    if d_is(res, d_bound(d_len(n))) == D_TRUE:
        res = d_zero(d_len(m))
    return res


def d_right(num):
    """右移"""
    res = '0'
    i = D_ZERO
    # i in range(d_len(num) - 1)
    while D_TRUE == D_TRUE:
        if d_is(i, d_prev(d_len(num))) == D_TRUE:
            break
        res = res + d_index(num, i)
        i = d_next(i)
    return res


def d_left(num):
    """左移"""
    res = '0'
    i = D_ZERO
    # i in range(d_len(num) - 1)
    while D_TRUE == D_TRUE:
        if d_is(i, d_prev(d_len(num))) == D_TRUE:
            break
        index = d_minus(d_minus(d_len(num), D_ONE), i)
        # res = num[-i - 1] + res
        res = d_index(num, index) + res
        i = d_next(i)
    return res


def d_frac(m, n):
    """除法"""
    # 如: 127/10 127-10=117
    if d_less(m, n) == D_TRUE:
        return d_zero(d_len(m)), m
    remainder = m
    quotient = d_zero(d_len(m))
    while True:
        remainder = d_minus(remainder, n)
        quotient = d_next(quotient)
        if d_less(remainder, n) == D_TRUE:
            break
    return quotient, remainder


def d_bin_exp(num):
    """整数的二进制表示"""
    exp = D_ZERO
    i = D_ZERO
    # i in range(d_len(num)):
    dlen = d_len(num)
    while D_TRUE == D_TRUE:
        if d_is(i, dlen) == D_TRUE:
            break
        index = d_minus(d_minus(dlen, D_ONE), i)
        # b = num[-i-1]
        b = d_index(num, index)
        bb = d_ten_to_bin(b)
        m, _ = d_mul(bb, d_power(D_TEN, i))
        exp, _ = d_plus(exp, m)
        i = d_next(i)
    return exp


def d_ten_exp(num):
    """
    整数的十进制表示
    循环商10取余
    以123为例说明: 123/10 = 12...3 12/10 = 1...2 1/10 = 0...1
    则3为最低位 2为次位 1为最高位
    """
    # 以123为例说明: 123/10 = 12...3 12/10 = 1...2 1/10 = 0...1
    # 3为最低位 2为次位 1为最高位
    exp = D_BLANK
    while D_TRUE == D_TRUE:
        num, r = d_frac(num, D_TEN)
        bt = d_bin_to_ten(r)
        exp = bt + exp
        if d_is(D_ZERO, num) == D_TRUE:
            break
    if exp == D_BLANK:
        exp = D_BIT_ZERO
    return exp


def d_cut_right_zeros_align(num):
    """截掉右侧的零,并对齐"""
    res = d_cut_right_zeros(num)
    i = D_ZERO
    # i in range(d_len(res), d_len(num))
    dlen = d_len(num)
    while D_TRUE == D_TRUE:
        if d_is(i, dlen) == D_TRUE:
            break
        res = D_BIT_ZERO + res
        i = d_next(i)
    return res


def d_cut_right_zeros(num):
    """截掉右侧的零"""
    res = D_BLANK
    join_flag = D_FALSE
    i = D_ZERO
    # i in range(d_len(num))
    dlen = d_len(num)
    while D_TRUE == D_TRUE:
        if d_is(i, dlen) == D_TRUE:
            break
        index = d_minus(d_minus(dlen, D_ONE), i)
        # b = num[-i-1]
        b = d_index(num, index)
        # 出现第一个0后则不再继续截断
        if join_flag == D_FALSE:
            if b == D_BIT_ONE:
                join_flag = D_TRUE
        if join_flag == D_TRUE:
            res = res + b
        i = d_next(i)
    return res


def d_ten_dec_exp(num):
    """
    小数部分的十进制表示
    放大位数,循环乘二进制的10,截取整数位,直至小数位为0
    例如:
    0.d1 d2 ... dn = d1*10^-1 + d2*10^-2 + ... + dn*10^-n
    d1.d2 ... dn = d1 + d2*10^-1 + ... + dn*10^-(n-1)
    TODO 效率低
    """
    exp = D_BLANK
    num_d = num
    while D_TRUE == D_TRUE:
        # num_d = 11111110
        if d_is(num_d, D_ZERO) == D_TRUE:
            break
        num_ex = d_expand_left(num_d)
        num_mul, _ = d_mul(num_ex, d_expand_left(D_TEN))
        num_i, num_d = d_float_bin_parts(num_mul)
        num_i_ten = d_bin_to_ten(num_i)
        exp = exp + num_i_ten
    return exp


def d_ten_to_bin(num):
    """十进制位转为二进制位"""
    if num == D_TEN_ONE:
        return D_ONE
    if num == D_TEN_TWO:
        return D_TWO
    if num == D_TEN_THREE:
        return D_THREE
    if num == D_TEN_FOUR:
        return D_FOUR
    if num == D_TEN_FIVE:
        return D_FIVE
    if num == D_TEN_SIX:
        return D_SIX
    if num == D_TEN_SEVEN:
        return D_SEVEN
    if num == D_TEN_EIGHT:
        return D_EIGHT
    if num == D_TEN_NINE:
        return D_NINE
    if num == D_TEN_ZERO:
        return D_ZERO
    # 表示错误,方便调试,实际应该抛出一个异常
    ex = Exception("二进制转换异常!")
    raise ex


def d_bin_to_ten(num):
    """二进制位转为十进制位"""
    if d_is(num, D_ONE) == D_TRUE:
        return D_TEN_ONE
    if d_is(num, D_TWO) == D_TRUE:
        return D_TEN_TWO
    if d_is(num, D_THREE) == D_TRUE:
        return D_TEN_THREE
    if d_is(num, D_FOUR) == D_TRUE:
        return D_TEN_FOUR
    if d_is(num, D_FIVE) == D_TRUE:
        return D_TEN_FIVE
    if d_is(num, D_SIX) == D_TRUE:
        return D_TEN_SIX
    if d_is(num, D_SEVEN) == D_TRUE:
        return D_TEN_SEVEN
    if d_is(num, D_EIGHT) == D_TRUE:
        return D_TEN_EIGHT
    if d_is(num, D_NINE) == D_TRUE:
        return D_TEN_NINE
    if d_is(num, D_ZERO) == D_TRUE:
        return D_TEN_ZERO
    # 表示错误,方便调试,实际应该抛出一个异常
    ex = Exception("十进制转换异常!")
    raise ex


def d_float_ten_exp(num):
    """浮点数的十进制表示"""
    i, d = d_float_bin_parts(num)
    exp_int = d_ten_exp(i)
    exp_deci = d_ten_dec_exp(d)
    exp = exp_int + '.' + exp_deci
    return exp


def d_float_bin_exp(num):
    """浮点数的二进制表示"""
    dot = '.'
    dlen = d_len(num)
    index = d_bin_exp(str(num.index(dot)))
    # i = num[0:index]
    i = d_slice(num, D_ZERO, index)
    # d = num[index + 1:]
    d = d_slice(num, d_next(index), dlen)
    exp_i = d_bin_exp(i)
    exp_d = d_bin_dec_exp(d)
    return exp_i + exp_d


def d_cut_left_zeros(num):
    res = D_BLANK
    join_flag = D_FALSE
    i = D_ZERO
    # i in range(d_len(num))
    dlen = d_len(num)
    while D_TRUE == D_TRUE:
        if d_is(i, dlen) == D_TRUE:
            break
        # b = num[i]
        b = d_index(num, i)
        # 出现第一个0后则不再继续截断
        if join_flag == D_FALSE:
            if b == D_BIT_ONE:
                join_flag = D_TRUE
        if join_flag == D_TRUE:
            res = b + res
        i = d_next(i)
    return res


def d_cut_left_zeros_align(num):
    """截掉左侧的零,然后右侧补零"""
    res = d_cut_left_zeros(num)
    i = d_len(res)
    # i in range(d_len(res), d_len(num))
    dlen = d_len(num)
    while D_TRUE == D_TRUE:
        if d_is(i, dlen) == D_TRUE:
            break
        res = res + D_BIT_ZERO
        i = d_next(i)
    return res


def d_align_right(num):
    """右侧补零"""
    # i in range(d_len(num), D_LENGTH)
    i = d_len(num)
    while D_TRUE == D_TRUE:
        if d_is(i, D_LENGTH) == D_TRUE:
            break
        num = num + D_BIT_ZERO
        i = d_next(i)
    return num


def d_float_bin_parts(num):
    """浮点数整数部分和小数部分的二进制表示"""
    le = d_len(num)
    # d_len_half = int(d_len(num) / 2)
    d_len_half, _ = d_frac(le, D_TWO)
    # int_part = num[:d_len_half]
    int_part = d_slice(num, D_ZERO, d_len_half)
    # decimal_part = num[d_len_half:]
    # from to
    # 00000000 00001000
    # from to
    # 00001000 00010000
    decimal_part = d_slice(num, d_len_half, le)
    return int_part, decimal_part


def d_mul_float(f1, f2):
    """
    浮点数乘法
    以1.5*1.25为例: i1 = 1 d1=0.5 i2 = 1 d2=0.25
    p1 = i1*i2 = 1
    p2 = i1*d2 = 0.25
    p3 = i2*d1 = 0.5
    p4 = 0.5*0.25 = 0.125
    """
    # 预留浮点数越界标识 TODO 扩容处理, 科学计数法
    of = D_FALSE
    i1, d1 = d_float_bin_parts(f1)
    i2, d2 = d_float_bin_parts(f2)
    # 记p1=i1*i2 p2=i1*d2 p3=i2*d1 p4=d1*d2

    p1_i, _ = d_mul(i1, i2)
    # f1整数部分乘f2小数部分
    p2_i, p2_d = d_mul_int_dec(i1, d2)
    # f2整数部分乘f1小数部分
    p3_i, p3_d = d_mul_int_dec(i2, d1)
    # f1小数部分乘f2小数部分
    p4_d = d_mul_dec(d1, d2)

    i, _ = d_plus(p1_i, p2_i)
    i, _ = d_plus(i, p3_i)
    d, _ = d_plus(p2_d, p3_d)
    d, _ = d_plus(d, p4_d)
    res = i + d
    return res


def d_expand_left(num):
    """扩容,长度变为原来的二倍,前面补零"""
    return d_zero(d_len(num)) + num


def d_expand_right(num):
    """扩容,长度变为原来的二倍,后面补零"""
    return num + d_zero(d_len(num))


def d_cut_right(num):
    """截掉右侧长度的一半"""
    # d_len_half = int(d_len(num) / 2)
    d_len_half, _ = d_frac(d_len(num), D_TWO)
    # res = num[:d_len]
    res = d_slice(num, D_ZERO, d_len_half)
    return res


def d_cut_left(num):
    """截掉左侧长度的一半"""
    # d_len = int(d_len(num) / 2)
    d_len_half, _ = d_frac(d_len(num), D_TWO)
    # res = num[d_len:]
    res = d_slice(num, d_len_half, d_len(num))
    return res


def d_mul_int_dec(m, n):
    """
    整数部分与小数部分相乘
    主要考虑越界问题,先扩充位数,再相乘,然后截出整数和小数部分
    """
    m_ex = d_expand_left(m)
    n_ex = d_expand_left(n)
    num, _ = d_mul(m_ex, n_ex)
    i, d = d_float_bin_parts(num)
    return i, d


def d_mul_dec(m, n):
    """
    小数部分相乘
    0.m * 0.n = m/10 * n/10 = mn/100
    """
    m_cut = d_cut_right_zeros(m)
    n_cut = d_cut_right_zeros(n)
    ma, na = d_alin(m_cut, n_cut)
    res, _ = d_mul(ma, na)
    res = d_align_right(res)
    res = d_right(res)
    res = d_right(res)
    return res


def d_alin(m, n):
    """
    两个数对齐
    以长度较大的数为基准
    """
    if d_len(m) < d_len(n):
        i = D_ZERO
        # i in range(d_len(n) - d_len(m))
        max = d_minus(d_len(n), d_len(m))
        while D_TRUE == D_TRUE:
            if d_is(i, max) == D_TRUE:
                break
            m = D_BIT_ZERO + m
            i = d_next(i)
    if d_len(m) > d_len(n):
        i = D_ZERO
        # i in range(d_len(m) - d_len(n))
        max = d_minus(d_len(m), d_len(n))
        while D_TRUE == D_TRUE:
            if d_is(i, max) == D_TRUE:
                break
            n = D_BIT_ZERO + n
            i = d_next(i)
    return m, n


def d_align_right(num):
    """右侧补零"""
    i = D_ZERO
    # i >=0 且 i < D_LENGTH 即i in range(0, D_LENGTH)
    while D_TRUE == D_TRUE:
        if d_is(i, D_LENGTH) == D_TRUE:
            break
        num = num + D_BIT_ZERO
        i = d_next(i)
    return num


def d_len(o_set):
    """
    返回num长度
    num可以是任意的有序集合,只需提供一个遍历方法
    """
    res = D_ZERO
    for n in o_set:
        res = d_next(res)
    return res


def d_index_of(o_set, e):
    """
    返回o_set中元素e的索引
    如果不存在则返回负一(注意不是-1)
    """
    i = D_ZERO
    for n in o_set:
        if d_is(n, e) == D_TRUE:
            return i
        i = d_next(i)
    return d_one_neg()


def d_equal(o1, o2):
    """
    比较两个集合是否相等
    """
    i1 = D_ZERO
    for e1 in o1:
        i2 = D_ZERO
        for e2 in o2:
            if d_is(i2, i1) == D_TRUE:
                break
            i2 = d_next(i2)
        # 元素比较是集合的应有之义
        if not e1 == e2:
            return D_FALSE
        i1 = d_next(i1)
    return D_TRUE


def d_index(o_set, index):
    """
    返回index位置的o_set集合元素
    index从0开始
    """
    # TODO 关于ZERO长度不足的问题
    # 关于负索引,-i即length-i-1
    # TODO 关于负数的规定
    i = D_ZERO
    # while d_bit_and(d_less_or_is(D_ZERO, i), d_less(i, d_len(o_set))) == D_TRUE:
    for n in o_set:
        if d_is(i, index) == D_TRUE:
            return n
        i = d_next(i)
    return '-1'


def d_slice(o_set, index_from, index_to):
    res = D_BLANK
    i = D_ZERO
    for n in o_set:
        if d_bit_and(d_less_or_is(index_from, i), d_less(i, index_to)) == D_TRUE:
            res = res + n
        i = d_next(i)
    return res


def d_bin_dec_exp(num):  # 25 = 2*10^2 + 5*10^1
    """
    十进制转二进制小数部分表示
    首先取各十进制位t1 t2 ... tn
    对于一个形如.t1 t2 ... tn的十进制数,其值为 t1*10^-1 + t2*10^-2 +... + tn*10^-n
    乘以10^n转为t1*10^(n-1) + t2*10(n-2) + ... + tn
    求出此数的二进制表示,然后除以10^n的二进制表示
    如0.25,放大100倍得25
    25 = (d*2^-1 + d*2^-2 + ... + d*2^-n) * 100
    两侧再同时乘以 2^n
    25 * 2^n = (d*2^(n-1) + d*2^(n-2) + ... + d) * 100
    然后再用(25 * 2^n)/100,得整数即为要求的小数部分
    这里的越界问题用增加位数处理
    """
    num_bin = d_bin_exp(num)
    scale_idx = d_bin_exp(str(len(num)))
    scale = d_power(D_TEN, scale_idx)
    num_bin_ex = d_expand_left(num_bin)
    d_ones_expand = d_next(d_expand_left(d_ones()))
    mul_ex, _ = d_mul(num_bin_ex, d_ones_expand)
    scale_ex = d_expand_left(scale)
    q, _ = d_frac(mul_ex, scale_ex)
    res = d_cut_left(q)
    return res


def test():
    global D_LENGTH
    # test_d_ten_dec_exp() # pass
    # test_d_mul() # pass
    # test_d_bin_dec_exp() # pass
    # test_d_mul_float() # TODO
    # test_d_float_bin_exp() # pass
    # test_d_bin_exp() # pass
    # test_d_float_ten_exp() # pass
    # test_d_ten_exp() # pass
    # test_d_next() # pass
    # test_d_frac() # pass
    # test_d_minus() # pass
    # test_d_ones_neg() # pass
    # test_d_prev() # pass
    # test_d_plus() # pass
    # test_d_len() # pass
    # test_d_index() # pass
    # test_d_xor() # pass
    # test_d_bit_xor() # pass
    # test_d_less() # pass
    # test_d_zero() # pass
    # test_py()
    # test_d_power() # pass


def test_d_power():
    m = '00001010'
    n = '00000010'
    r = d_power(m, n)
    print(d_ten_exp(r))


def test_d_zero():
    n = D_TEN
    r = d_zero(n)
    print(r)


def test_d_less():
    m = '0000000000000001'
    n = '0000000000001010'
    r = d_less(m, n)
    print(r)


def test_d_plus():
    m = '00000010'
    n = '00000111'
    r, _ = d_plus(m, n)
    print(r)


def test_py():
    s = '123'
    sl = list(s)
    print(sl.pop())


def test_d_bit_xor():
    m = '1'
    n = '1'
    r = d_bit_xor(m, n)
    # 0
    print(r)

    m = '0'
    n = '0'
    r = d_bit_xor(m, n)
    # 0
    print(r)

    m = '1'
    n = '0'
    r = d_bit_xor(m, n)
    # 1
    print(r)

    m = '0'
    n = '1'
    r = d_bit_xor(m, n)
    # 1
    print(r)


def test_d_is():
    num1 = "00000000"
    num2 = "00000010"
    r = d_is(num1, num2)
    print(r)


def test_d_xor():
    # m = n 当且仅当 m xor n = 零
    # m = '00000000'
    # n = '00000000'
    # r = d_xor(m, n)
    # # 00000000
    # print(r)

    # m = '11111111'
    # n = '11111111'
    # r = d_xor(m, n)
    # print(r)

    m = '11111011'
    n = '11111011'
    r = d_xor(m, n)
    print(r)


def test_d_index():
    num = '123'
    index = D_TWO
    r = d_index(num, index)
    print(r)


def test_d_len():
    num = '123'
    l = d_len(num)
    print(l)


def test_d_ten_dec_exp():
    num = '00100000'
    r = d_ten_dec_exp(num)
    print(r)


def test_d_mul():
    # m = '4'
    # n = '4'
    # m_bin = d_bin_exp(m)
    # n_bin = d_bin_exp(n)
    # r, o = d_mul(m_bin, n_bin)
    # r_ten = d_ten_exp(r)
    # print(r_ten)
    # '0000000011111110'
    # '0000000000001010'
    m_bin = '0000000011111110'
    n_bin = '0000000000001010'
    r, o = d_mul(m_bin, n_bin)
    #      10011110110
    # 0000000100010000'
    # r_ten = d_ten_exp(r)
    print(r)


def test_d_bin_dec_exp():
    m = '25'
    r = d_bin_dec_exp(m)
    print(r)


def test_d_mul_float():
    m = '10.5'
    n = '10.25'
    # m = d_float_bin_exp(m)
    m = '0000101010000000'
    # n = d_float_bin_exp(n)
    n = '0000101001000000'
    r = d_mul_float(m, n)
    # rt = d_float_ten_exp(r)
    print(r)


def test_d_float_bin_exp():
    m = '1.01'
    r = d_float_bin_exp(m)
    print(r)


def test_d_bin_exp():
    m = '127'
    r = d_bin_exp(m)
    print(r)


def test_d_float_ten_exp():
    #   '7654321001234567'
    m = '0000000100011001'
    r = d_float_ten_exp(m)
    print(r)
    m = '0000000110000000'
    r = d_float_ten_exp(m)
    print(r)


def test_d_ten_exp():
    m = '01111111'
    r = d_ten_exp(m)
    print(r)


def test_d_next():
    m = '11111111'
    r = d_next(m)
    print('test_d_next: ', r)


def test_d_prev():
    # m = '01111111'
    # r = d_prev(m)
    # print(r)

    # m = '11111111'
    # r = d_prev(m)
    # print(r)

    m = '00001010'
    r = d_prev(m)
    print(r)


def test_d_ones_neg():
    r = d_one_neg(D_LENGTH)
    print(r)


def test_d_minus():
    m = '00000000'
    n = '00000010'
    r = d_minus(m, n)
    print("test_d_minus:", r)


def test_d_frac():
    m = '01111111'  # 127
    n = '00001010'  # 10
    d, r = d_frac(m, n)
    print("test_d_frac:", d_ten_exp(d), d_ten_exp(r))


def pi_ele(k):
    kex = d_expand_right(k)
    ONE = d_expand_right(D_ONE)
    TWO = d_expand_right(D_TWO)
    dm, _ = d_mul(TWO, kex)
    dp, _ = d_plus(dm, ONE)
    res, _ = d_frac(ONE, dp)
    return res


def pi(k):
    # pi / 4 = 1 - 1/3 + 1/5 - 1/7 + ..... + (-1)^k (1 / (2k+1) ) + ....
    pi = d_expand_left(D_ZERO)
    i = D_ZERO
    while D_TRUE == D_TRUE:
        if d_is(i, k) == D_TRUE:
            break
        _, r = d_frac(i, D_TWO)
        if d_is(r, D_ZERO):
            pi = d_plus(pi, pi_ele(i))
        else:
            pi = d_minus(pi, pi_ele(i))
        i = d_next(i)
    print(pi)


# 主方法
if __name__ == '__main__':
    # TODO 科学计数法解决乘法效率问题
    test()
    pi(D_FOUR)

\