# -*- coding: utf-8 -*-
# 高精度计算器 v0.9.0 (Python 3.7)
from decimal import Decimal, getcontext
import re
import os
import math

# 设置控制台颜色：黑底白字 (0x0F)
os.system('color 0F')

getcontext().prec = 30

# ----- 自定义数学函数（高精度包装）-----
def factorial(x):
    """计算整数阶乘，返回 Decimal"""
    return Decimal(math.factorial(int(x)))

def sqrt(x):
    """计算平方根，返回 Decimal"""
    return Decimal(x).sqrt()

def log(x):
    """常用对数（以10为底），返回 Decimal"""
    return Decimal(str(math.log10(float(x))))

def ln(x):
    """自然对数（以e为底），返回 Decimal"""
    return Decimal(str(math.log(float(x))))

def sin(x):
    """正弦（弧度制），返回 Decimal"""
    return Decimal(str(math.sin(float(x))))

def cos(x):
    """余弦（弧度制），返回 Decimal"""
    return Decimal(str(math.cos(float(x))))

def tan(x):
    """正切（弧度制），返回 Decimal"""
    return Decimal(str(math.tan(float(x))))

# 允许的数学函数白名单
ALLOWED_FUNCS = {
    "factorial": factorial,
    "sqrt": sqrt,
    "log": log,
    "ln": ln,
    "sin": sin,
    "cos": cos,
    "tan": tan
}

def safe_calc(expr):
    # 允许的字符：数字、运算符、括号、空格、小数点、函数名（字母）、阶乘符号 '!'
    allowed_chars = '0123456789+-*/() .!abcdefghijklmnopqrstuvwxyz'
    if any(c not in allowed_chars for c in expr.lower()):
        raise ValueError("表达式含有非法字符")

    # 处理阶乘：将 "数字!" 替换为 "factorial(数字)"
    expr = re.sub(r'(\d+)!', r'factorial(\1)', expr)

    # 将数字字面量替换为 Decimal('数字')
    safe_expr = re.sub(r'\b\d+(?:\.\d+)?\b', lambda m: "Decimal('{}')".format(m.group()), expr)

    # 准备 eval 的命名空间：只包含 Decimal 和允许的函数
    namespace = {"Decimal": Decimal}
    namespace.update(ALLOWED_FUNCS)

    try:
        result = eval(safe_expr, namespace, {})
        return result
    except Exception as e:
        raise ValueError("计算错误: " + str(e))

def format_result(result):
    s = str(result)
    if '.' in s:
        s = s.rstrip('0').rstrip('.')
    return s

def main():
    print("===========================计算器 v0.9.0α===========================")
    print("作者：eer4 | 2026年03月27日")
    print("基于 Python 3.7.0")
    print("支持运算：加(+)、减(-)、乘(*)、除(/)、幂(**)、阶乘(!)、开方(sqrt())")
    print("        对数(log, ln)、三角函数(sin, cos, tan) 弧度制")
    print("输入“help”查看帮助 | “about”关于 | “exit”退出")
    print("注意：一定要按“exit”退出，不然程序挂了后果自负！！！")
    print("      Python 2.4.0、2.5.2、2.6.3就是这样挂掉的！！！")
    print("=====================================================================")

    while True:
        expr = input("\n>>> ").strip()
        if expr.lower() == 'exit':
            break
        elif expr.lower() == 'about':
            print("\n~~~~~~~~~~~~~~~~~~~~~~~~~计算器 v0.9.0α~~~~~~~~~~~~~~~~~~~~~~~~~")
            print("基于 Python 3.7.0")
            print("支持运算：")
            print("  四则运算：+ - * /")
            print("  幂运算：**  例如 2**10 = 1024")
            print("  阶乘：!    例如 5! = 120")
            print("  开方：sqrt()  例如 sqrt(2) = 1.414213562...")
            print("  对数：log() 常用对数（底10），ln() 自然对数")
            print("  三角函数：sin()、cos()、tan() 弧度制")
            print("精确计算：例如 0.1+0.2 = 0.3")
            print("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~")
            continue
        elif expr.lower() == 'help':
            print("\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~可用指令：~~~~~~~~~~~~~~~~~~~~~~~~~~~~~")
            print("  about  - 显示关于信息")
            print("  help   - 显示本帮助")
            print("  exit   - 退出程序")
            print("运算示例：")
            print("  3+5*2         -> 13")
            print("  (1+2)/3       -> 1")
            print("  2**10         -> 1024")
            print("  5!            -> 120")
            print("  sqrt(2)       -> 1.414213562...")
            print("  log(100)      -> 2")
            print("  ln(2.7182818) -> 约 1")
            print("  sin(3.14159/2) -> 约 1")
            print("  0.1+0.2       -> 0.3")
            print("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~")
            continue
        if not expr:
            continue
        try:
            result = safe_calc(expr)
            out = format_result(result)
            print(out)
        except Exception as e:
            print("[错误] {}".format(e))

if __name__ == "__main__":
    main()
