|
- # !/usr/bin/env python
- # -*- coding: utf-8 -*-
- """
- @Time : 2020/11/5 19:30
- @Author : Albert Darren
- @Contact : 2563491540@qq.com
- @File : ValidNumber.py
- @Version : Version 1.0.0
- @Description : TODO 获得有效数字位数
- @Created By : PyCharm
- """
- from decimal import Decimal, getcontext
-
-
- # 自定义一个非法输入数字异常类
- class IllegalNumber(Exception):
- def __init__(self, decimal_number):
- self.decimal_number = decimal_number
-
- def __str__(self):
- return "Illegal input:{},Not int or float".format(self.decimal_number)
-
-
- def significant_figures(decimal_number: (int, float), precision=30):
- """
- 返回指定十进制数字有效数字位数,不包括科学计数法表示的数字
- :param precision: 准确值精度
- :param decimal_number: integer or float
- :return: the number of significant digits in a decimal number.
- """
- # getcontext().prec=precision
- # accuracy_value=Decimal((-1+pow(5, 0.5))/2)
- # absolute_error_limit=1
-
- # 将decimal_number转化为字符串类型
- decimal_number = str(decimal_number)
- # 输入合法性判断,eval内置函数可以检查部分非法情况
- if isinstance(eval(decimal_number), (int, float)):
- decimal_number = decimal_number.lstrip('-.0') # 去掉最左边的负号-,小数点.和无效的0
- # 获得当前十进制数的长度
- sig_digits = len(decimal_number)
- # 判断小数点是否在sig_digits中
- if "." in decimal_number:
- # 小数点在sig_digits中就减去1
- sig_digits -= 1
- return sig_digits
- else:
- # 输入不合法,抛出eval不能检出的异常
- raise IllegalNumber(decimal_number)
-
-
- def iterate_positive_root(x0=1, iteration_depth=5):
- """
- 迭代法求一元二次方程正根的近似解x*
- :param x0: 初始近似值,默认为1
- :param iteration_depth: 迭代次数或深度,默认是5次
- :return: 方程的近似解
- """
- x = x0
- for i in range(iteration_depth):
- x = 1 / (1 + x)
- return x0, iteration_depth, x
-
-
- def iterate_sqrt(radicand: (int, float), initial_value: (int, float), precision: float = -9):
- """
- 返回在指定精度和初始近似值下的被开方数的平方根
- :param radicand:被开方数
- :param initial_value:初始近似值x0
- :param precision:迭代计算精度,用幂指数表示精度,默认为-9,即10的﹣9次方或者1e-09
- :return:the square root of radicand
- """
- # 默认高精度浮点运算为28位,包括整数位和小数位,设置准确值的位数
- getcontext().prec = abs(precision) + 2
- sqrt = initial_value
- # 准确值
- accuracy_value = pow(Decimal(radicand), Decimal(0.5))
- # 绝对误差
- absolute_error = 0.5 * pow(10, precision)
- # 计数器,统计迭代次数
- count = 0
- while 1:
- # 迭代误差
- error = abs(accuracy_value - Decimal(sqrt))
- if error < absolute_error:
- return radicand, initial_value, count, accuracy_value, sqrt
- sqrt = 0.5 * (sqrt + radicand / sqrt)
- count += 1
-
-
- """
- abs(0.6153846153846154-0.6180339887498948)
- 0.0026493733652793727
- """
-
- if __name__ == '__main__':
- result = iterate_positive_root()
- print("""
- 初始近似值x0={},
- 迭代{}次,
- 得到该方程的正根近似解x*={}的有效数字位数为:{}
- """.format(result[0], result[1], result[2], significant_figures(str(result[2]))))
- # 准确值:0.61803398874989484820458683436564
- # 近似值:0.6180339887498948
- # 下面是函数significant_figures的调试测试
- # answer = input("请输入十进制数字:")
- # while 1:
- # print("数字{}的有效数字位数为:{}".format(answer, significant_figures(answer)))
- # answer = input("请输入十进制数字或者按enter键结束:")
- # if answer == "":
- # break
|