def s_newton(self): """ 利用牛顿迭代计算算数平方根 :return: 最终的结果 """ start_num = '1' # 判断当前解是否满足条件,保证正确性,此时多保留几位 if self.s == 'p': leave_count = self.d + self.l + self.change elif self.s == 's': leave_count = self.d + self.l + self.change + self.add # 依然是根据精度判断 while not self.control_p(start_num, leave_count): # a = (a + (self.n/a)) /2 # 保留位数也要稍微大点 start_num = b_d.big_division( str( b_s_a.big_addition( start_num, str( b_d.big_division('%s' % self.n, start_num, leave_count * 3)))), '2', leave_count * 3) return self.get_result(start_num, self.s)
def sqrt_2_dichotomy(decimal): """ 利用二分法计算2的算数平方根,和直接法不同,此法是通过得到的乘积和2的差来判断是否终止 :param decimal: 乘积与2的差,绝对值小于1e(-decomical) :return: 2的算数平方根 """ min_num = '0' # 二分法开始的最小值 max_num = '2' # 二分法开始的最大值 middle_num = '' # 二分法开始的中间值 product = '1' # 通过判断当前乘积和2的差是否满足条件 while not accuracy(product, decimal): # 计算中间值,注意中间值的精度稍微大于decimal即可。 # 平方根的精确位数和乘积的精确位数基本相等 # 如果平方根的前M位是精确的,那么其平方和2的差值小数点后面连续为0的个数基本也是M个。但这并不是绝对的 middle_num = str( b_d.big_division(b_s_a.big_addition(min_num, max_num), '2', decimal + 5)) # 计算乘积 product = b_p.big_product(middle_num, middle_num) # 判断大小 compare_result = compare_number(product) if compare_result == 1: # 大值变小 max_num = middle_num elif compare_result == -1: # 小值变大 min_num = middle_num return middle_num, product
def s_dichotomy(self): """ 利用二分法计算算数平方根 :return: 最终的结果 """ min_num = '0' # 二分法开始的最小值 max_num = '4' # 二分法开始的最大值 middle_num = '2.' # 二分法开始的中间值 # 判断当前解是否满足条件,保证正确性,此时多保留几位 if self.s == 'p': leave_count = self.d + self.l + self.change elif self.s == 's': leave_count = self.d + self.l + self.change + self.add # 依然是根据精度判断 while not self.control_p(middle_num, leave_count): # 注意因为中间值的精确度小的话,会导致每次的middle_num 不变,因此下面的精度要稍微大点 middle_num = str( b_d.big_division(b_s_a.big_addition(min_num, max_num), '2', leave_count * 3)) # 计算乘积 product = b_p.big_product(middle_num, middle_num) # 判断大小 compare_result = self.compare_number(product) if compare_result == 1: # 大值变小 max_num = middle_num elif compare_result == -1: # 小值变大 min_num = middle_num else: return self.get_result(middle_num, self.s) return self.get_result(middle_num, self.s)
def sqrt_2_newton(decimal): """ 利用牛顿迭代f计算2的算数平方根,和二分法相同,此法也是通过得到的乘积和2的差来判断是否终止 :param decimal: 乘积与2的差,绝对值小于1e(-decomical) :return: 2的算数平方根 """ start_num = '1' product = '1' # 通过判断当前乘积和2的差是否满足条件 while not accuracy(product, decimal): # a = (a + (2/a)) /2 # 保留位数也要比decimal稍微大点 start_num = b_d.big_division( b_s_a.big_addition(start_num, b_d.big_division('2', start_num, decimal + 5)), '2', decimal + 5) # 计算乘积 product = b_p.big_product(start_num, start_num) return start_num, product
def sqrt_2_sequence(decimal): """ 构造数对。数对元素之间的商值看作根号2的近似。 和二分法、牛顿迭代法相同,此法也是通过得到的乘积和2的差来判断是否终止 :param decimal: 小数的精度 :return: """ # 初始数对 s = ['1', '1'] # 初始比值 radio = '1' # 乘积 product = '1' # 通过判断当前乘积和2的差是否满足条件 while not accuracy(product, decimal): c_s = s.copy() # 构造下一个数对 s[0] = b_s_a.big_addition(c_s[0], c_s[1]) s[1] = b_s_a.big_addition(str(b_p.big_product('2', c_s[0])), c_s[1]) # 计算比值,保留位数也要比decimal稍微大点 radio = str(b_d.big_division(s[1], s[0], decimal + 5)) # 计算乘积 product = b_p.big_product(radio, radio) return radio, product