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)
\