-- author: https://github.com/ChaosAlphard -- 说明 https://github.com/gaboolic/rime-shuangpin-fuzhuma/pull/41 -- 原有功能: -- 单个随机数生成、三角函数、幂函数、指数函数、对数函数求值 -- 计算n次方根、平均值、方差、阶乘、角度与弧度的相互转化 -- 新增功能: -- 求解一元一次方程、二元一次方程组、一元二次方程、一元三次方程、一元四次方程; -- 求解一次、二次函数解析式、圆的方程; -- 取整函数(包括向上取整和向下取整)、求余函数; -- 已知数列中任意两项,求通项公式(等差或等比);求数列的前n项和(等差或等比); -- 已知三角形三边长,求面积;已知正多边形边数n、边长a,求面积; -- 判断两直线位置关系,给出距离或交点坐标;点到点、点到直线距离求解; -- 求解两点间线段的垂直平分线方程;求解点绕点旋转后的坐标; -- 组合数、排列数、最大公因数、最小公倍数求解; -- 点关于直线的对称点坐标、直线关于直线(或点)的对称直线方程求解; -- 连续自然数的幂方求和,包括平方和、立方和、4次方之和;前n个奇数或偶数的平方和、立方和、4次方之和; -- 求解勾股数、批量随机数、质因数分解、找质数; -- 24点计算器(姑且算一个小游戏,雾); -- 常见单位间的换算;数字的进制转换; -- 功能引导键一览: -- cb = "连续自然数立方和(从1开始)" -- fp = "连续自然数4次方之和(从1开始)" -- sq = "连续自然数平方和(从1开始)" -- tx = "已知数列的任意两项aᵢ、aₖ及对应的项数i、k,求其通项公式" -- avg = "平均值" -- cos = "余弦" -- deg = "弧度转换为角度" -- dds = "顶点式求解二次函数解析式" -- dxf = "点斜法求解一次函数解析式" -- ecb = "前n个偶数的立方和" -- efp = "前n个偶数的4次方之和" -- esq = "前n个偶数的平方和" -- exp = "返回 e^x" -- gbs = "计算多个数的最小公倍数" -- ggs = "求解勾股数" -- gys = "计算多个数的最大公因数" -- hls = "计算行列式" -- ldf = "两点法求解一次函数解析式" -- ld1 = "已知两点坐标,求两点间的距离" -- ld2 = "已知两点坐标,求两点间线段的垂直平分线方程" -- ld3 = "已知两点P(x₁, y₁)和Q(x₂, y₂),求点P绕点Q旋转角度a(角度制)后的P'坐标" -- log = "x作为底数的对数" -- mod = "求余函数" -- msq = "计算正数的算术平方根" -- nrt = "计算 x 开 N 次方" -- ocb = "前n个奇数的立方和" -- ofp = "前n个奇数的4次方之和" -- osq = "前n个奇数的平方和" -- pls = "计算排列数" -- rad = "角度转换为弧度" -- sin = "正弦" -- sjs = "随机数" -- tan = "正切" -- tfp = "24点计算器" -- var = "方差" -- ybs = "一般式求解二次函数解析式" -- zhs = "计算组合数" -- zys = "质因数分解" -- zzs = "找质数" -- acos = "反余弦" -- asin = "反正弦" -- atan = "反正切" -- cesd = "已知圆上不同三点的坐标,求圆方程" -- cexl = "已知圆心和圆上不同两点的坐标求圆方程" -- cexr = "已知圆心坐标和半径求圆的方程" -- cosh = "双曲余弦" -- dbsl = "已知等比数列的首项a₁,公比q,求指定的前n项和" -- dcsl = "已知等差数列的首项a₁,公差d,求指定的前n项和" -- dwhs = "单位换算,支持面积、质量、长度、体积,(数字, '原单位', '目标单位')" -- eyyc = "求解二元一次方程组ax+by=e,cx+dy=f" -- fact = "阶乘" -- lzx1 = "已知两直线方程A₁x+B₁y+C₁=0和A₂x+B₂y+C₂=0,判断它们的位置关系" -- lzx2 = "已知直线l₁:A₁x+B₁y+C₁=0和l₂:A₂x+B₂y+C₂=0,求两条直线以彼此为轴的对称直线方程" -- loge = "e作为底数的对数" -- logt = "10作为底数的对数" -- jzzh = "数字进制转换,支持2~36进制,(数字, 原进制, 目标进制)" -- psjs = "批量随机数" -- sinh = "双曲正弦" -- sjxx = "已知三角形三个顶点坐标,求其“心”的坐标" -- sjx1 = "已知三角形的三边长a、b、c,求三角形面积" -- sjx2 = "已知三角形的三个顶点坐标(x₁,y₁),(x₂,y₂),(x₃,y₃),求三角形面积" -- sqrt = "计算复数的平方根" -- tanh = "双曲正切" -- tcr1 = "已知两圆标准方程(x-x₁)²+(y-y₁)²=r₁²和(x-x₂)²+(y-y₂)²=r₂²,判断它们的位置关系" -- tcr2 = "已知两圆一般方程x²+y²+D₁x+E₁y+F₁=0和x²+y²+D₂x+E₂y+F₂=0,判断它们的位置关系" -- yyec = "求解一元二次方程" -- yyyc = "求解一元一次方程" -- xsqz = "向上取整" -- xxqz = "向下取整" -- zdbx = "已知边数n与边长a计算正多边形面积" -- atan2 = "返回以弧度为单位的点(x,y)相对于x轴的逆时针角度" -- dyzx1 = "已知一点坐标(x₁,y₁)和直线方程Ax+By+C=0,求点到直线的距离及对称点坐标" -- dyzx2 = "已知一点P(x₁,y₁)和直线l:Ax+By+C=0,求直线l关于点P的对称直线l'的方程" -- ldexp = "返回 x*2^y" -- sjxy1 = "已知三角形三边长,求内切圆半径和外接圆半径" -- sjxy2 = "已知三角形三个顶点坐标,求内切圆半径和外接圆半径" -- yysc1 = "求解一元三次方程" -- yysc2 = "求解一元四次方程" local T = {} function T.init(env) local config = env.engine.schema.config env.name_space = env.name_space:gsub('^*', '') local _calc_pat = config:get_string("recognizer/patterns/calculator") or nil T.prefix = _calc_pat and _calc_pat:match("%^.?([a-zA-Z/=]+).*") or "V" T.tips = config:get_string("calculator/tips") or "计算器" end local function startsWith(str, start) return string.sub(str, 1, string.len(start)) == start end -- 函数表 local calc_methods = { -- e, exp(1) = e^1 = e e = math.exp(1), -- π pi = math.pi, b = 10 ^ 2, q = 10 ^ 3, k = 10 ^ 3, w = 10 ^ 4, tw = 10 ^ 5, m = 10 ^ 6, tm = 10 ^ 7, y = 10 ^ 8, g = 10 ^ 9 } local methods_desc = { ["e"] = "自然常数, 欧拉数", ["pi"] = "圆周率 π", ["b"] = "百", ["q"] = "千", ["k"] = "千", ["w"] = "万", ["tw"] = "十万", ["m"] = "百万", ["tm"] = "千万", ["y"] = "亿", ["g"] = "十亿" } -- 实现计算输入 local function replaceToFactorial(str) return str:gsub("([0-9]+)!", "fact(%1)") end -- 保留返回值的非零有效数字(返回结果为数字) local function fn(n) -- 将数字转换为字符串以便处理 local s = tostring(n) -- 查找小数点的位置 local i = string.find(s, "%.") if i == nil then -- 如果没有小数点,直接返回原数字 return n end -- 去除小数点后的尾随零 local j = string.len(s) while j > i and string.sub(s, j, j) == "0" do j = j - 1 end -- 如果小数点后没有数字了,移除小数点 if j == i then -- 返回整数部分 return tonumber(string.sub(s, 1, i - 1)) else -- 否则,返回处理后的数字 return tonumber(string.sub(s, 1, j)) end end -- 保留返回值的非零有效数字(返回结果为字符串) local function fs(n) -- 将数字转换为字符串以便处理 local s = tostring(n) -- 查找小数点的位置 local i = string.find(s, "%.") if i == nil then -- 如果没有小数点,直接返回原数字 return n end -- 去除小数点后的尾随零 local j = string.len(s) while j > i and string.sub(s, j, j) == "0" do j = j - 1 end -- 如果小数点后没有数字了,移除小数点 if j == i then -- 返回整数部分 return string.sub(s, 1, i - 1) else -- 否则,返回处理后的数字 return string.sub(s, 1, j) end end -- 向上取整函数 local function ceil(x) return math.ceil(x) end calc_methods["xsqz"] = ceil methods_desc["xsqz"] = "向上取整" -- 向下取整函数 local function floor(x) return math.floor(x) end calc_methods["xxqz"] = floor methods_desc["xxqz"] = "向下取整" -- 四舍五入保留小数点后n位 local function round(m, n) local factor = 10 ^ n return floor(m * factor + 0.5) / factor end local function format_number_for_display(n) if type(n) ~= "number" then return tostring(n) end -- 分离整数部分和小数部分 local integer_part = math.floor(math.abs(n)) local integer_digits = #tostring(integer_part) -- 只检查整数部分的位数 if integer_digits > 19 then return "数字超限!" end -- 检查是否为整数 if n == math.floor(n) then return tostring(math.floor(n)) end -- 四舍五入到12位小数 local rounded = round(n, 12) -- 使用fs函数转换为字符串并去除尾随0 return fs(rounded) end -- 计算两个数的最大公因数(GCD) local function gcd(a, b) while b ~= 0 do local temp = b b = a % b a = temp end return a end -- 计算多个数的最大公因数 local function gcd_multiple(...) local nums, result nums = { ... } result = nums[1] for i = 2, #nums do result = gcd(result, nums[i]) end return fn(result) end calc_methods["gys"] = gcd_multiple methods_desc["gys"] = "计算多个数的最大公因数" -- 计算两个数的最小公倍数(LCM) local function lcm(a, b) return a * b / gcd(a, b) end -- 计算多个数的最小公倍数 local function lcm_multiple(...) local nums, result nums = { ... } result = nums[1] for i = 2, #nums do result = lcm(result, nums[i]) end return fn(result) end calc_methods["gbs"] = lcm_multiple methods_desc["gbs"] = "计算多个数的最小公倍数" -- random(m ,n) 返回m-n之间的随机数,n为空则返回1-m之间,都为空则返回0-1之间的小数 local function random(...) return math.random(...) end -- 注册到函数表中 calc_methods["sjs"] = random methods_desc["sjs"] = "随机数" -- 计算开 N 次方 local function nth_root(x, n) if n % 2 == 0 and x < 0 then return nil -- 偶次方时负数没有实数解 elseif x < 0 then return -((-x) ^ (1 / n)) else return x ^ (1 / n) end end calc_methods["nrt"] = nth_root methods_desc["nrt"] = "计算 x 开 N 次方" -- 正弦 local function sin(x) return math.sin(x) end calc_methods["sin"] = sin methods_desc["sin"] = "正弦" -- 双曲正弦 local function sinh(x) return (math.exp(x) - math.exp(-x)) / 2 end calc_methods["sinh"] = sinh methods_desc["sinh"] = "双曲正弦" -- 反正弦 local function asin(x) return math.asin(x) end calc_methods["asin"] = asin methods_desc["asin"] = "反正弦" -- 余弦 local function cos(x) return math.cos(x) end calc_methods["cos"] = cos methods_desc["cos"] = "余弦" -- 双曲余弦 local function cosh(x) return (math.exp(x) + math.exp(-x)) / 2 end calc_methods["cosh"] = cosh methods_desc["cosh"] = "双曲余弦" -- 反余弦 local function acos(x) return math.acos(x) end calc_methods["acos"] = acos methods_desc["acos"] = "反余弦" -- 正切 local function tan(x) return math.tan(x) end calc_methods["tan"] = tan methods_desc["tan"] = "正切" -- 双曲正切 local function tanh(x) local e = math.exp(2 * x) return (e - 1) / (e + 1) end calc_methods["tanh"] = tanh methods_desc["tanh"] = "双曲正切" -- 反正切 local function atan(x) return math.atan(x) end calc_methods["atan"] = atan methods_desc["atan"] = "反正切" -- 返回以弧度为单位的点(x,y)相对于x轴的逆时针角度。y是点的纵坐标,x是点的横坐标 -- 返回范围从−π到π (以弧度为单位),其中负角度表示向下旋转,正角度表示向上旋转 -- 它与传统的 math.atan(y/x) 函数相比,具有更好的数学定义,因为它能够正确处理边界情况(例如x=0) local function atan2(y, x) if x == 0 and y == 0 then return 0 / 0 -- 返回NaN elseif x == 0 and y ~= 0 then if y > 0 then return math.pi / 2 else return -math.pi / 2 end else return math.atan(y / x) + (x < 0 and math.pi or 0) end end calc_methods["atan2"] = atan2 methods_desc["atan2"] = "返回以弧度为单位的点(x,y)相对于x轴的逆时针角度" -- 将角度从弧度转换为度 local function deg(x) return math.deg(x) end calc_methods["deg"] = deg methods_desc["deg"] = "弧度转换为角度" -- 将角度从度转换为弧度 local function rad(x) return math.rad(x) end calc_methods["rad"] = rad methods_desc["rad"] = "角度转换为弧度" -- 返回 x*2^y local function ldexp(x, y) return x * 2 ^ y end calc_methods["ldexp"] = ldexp methods_desc["ldexp"] = "返回 x*2^y" -- 返回 e^x local function exp(x) -- 检查参数正确性 if type(x) ~= "number" then return "参数必须是数字" end return math.exp(x) end calc_methods["exp"] = exp methods_desc["exp"] = "返回 e^x" -- 计算复数的平方根 local function sqrt(...) local data = {...} local n = #data local a,b if n == 0 then return "请输入至少一个数" elseif n > 2 then return "参数数量不能超过2个" end -- 检查参数正确性 for i = 1, n do if type(data[i]) ~= "number" then return "参数必须是数字" end end if n == 1 then a = data[1] b = 0 elseif n == 2 then a = data[1] b = data[2] end local t1 = (math.sqrt(a ^ 2 + b ^ 2) + a) / 2 local t2 = (math.sqrt(a ^ 2 + b ^ 2) - a) / 2 local x1, x2, y1, y2 x1 = fn(math.sqrt(t1)) x2 = fn(-math.sqrt(t1)) y1 = fn(math.sqrt(t2)) y2 = fn(-math.sqrt(t2)) if a == 0 and b == 0 then return 0 elseif a ~= 0 and b == 0 then if a > 0 then return x1 .. " , " .. x2 else return y1 .. "i" .. " , " .. y2 .. "i" end elseif b ~= 0 then if b > 0 then return x1 .. "+" .. y1 .. "i" .. " , " .. x2 .. "-" .. -y2 .. "i" else return x1 .. "-" .. -y2 .. "i" .. " , " .. x2 .. "+" .. y1 .. "i" end end end calc_methods["sqrt"] = sqrt methods_desc["sqrt"] = "计算复数的平方根" -- 计算正数的算术平方根 local function msq(x) -- 检查参数正确性 if type(x) ~= "number" then return "参数必须是数字" end if x < 0 then return "参数必须是非负数" end return fn(math.sqrt(x)) end calc_methods["msq"] = msq methods_desc["msq"] = "计算正数的算术平方根" -- x为底的对数, log(10, 100) = log(100) / log(10) = 2 local function log(x, y) -- 不能为负数或0 if x <= 0 or y <= 0 then return nil end return math.log(y) / math.log(x) end calc_methods["log"] = log methods_desc["log"] = "x作为底数的对数" -- 自然数e为底的对数 local function loge(x) -- 不能为负数或0 if x <= 0 then return nil end return math.log(x) end calc_methods["loge"] = loge methods_desc["loge"] = "e作为底数的对数" -- 10为底的对数 local function logt(x) -- 不能为负数或0 if x <= 0 then return nil end return math.log(x) / math.log(10) end calc_methods["logt"] = logt methods_desc["logt"] = "10作为底数的对数" -- 平均值 local function avg(...) local data, n, sum data = { ... } n = #data sum = 0 -- 样本数量不能为0 if n == 0 then return nil end -- 计算总和 for _, value in ipairs(data) do sum = sum + value end return fn(sum / n) end calc_methods["avg"] = avg methods_desc["avg"] = "平均值" -- 方差 local function variance(...) local data, n, sum, mean, sum_squared_diff data = { ... } n = #data sum = 0 sum_squared_diff = 0 -- 样本数量不能为0 if n == 0 then return nil end -- 计算均值 for _, value in ipairs(data) do sum = sum + value end mean = sum / n -- 计算方差 for _, value in ipairs(data) do sum_squared_diff = sum_squared_diff + (value - mean) ^ 2 end return fn(sum_squared_diff / n) end calc_methods["var"] = variance methods_desc["var"] = "方差" -- 阶乘 local function factorial(x) -- 不能为负数 if x < 0 then return nil elseif x == 0 or x == 1 then return 1 end local result = 1 for i = 1, x do result = result * i end return fn(result) end calc_methods["fact"] = factorial methods_desc["fact"] = "阶乘" -- 计算行列式 local function hls(...) local args, n1, sqrt_n, matrix, index, side_length args = { ... } n1 = #args sqrt_n = math.sqrt(n1) -- 判断n1是否为完全平方数,如果是,则将输入的元素重新排列成一个方阵 if sqrt_n == math.floor(sqrt_n) then matrix = {} index = 1 side_length = math.floor(sqrt_n) for i = 1, side_length do matrix[i] = {} for j = 1, side_length do matrix[i][j] = args[index] index = index + 1 end end else return "给出的元素不能组成一个方阵。" end -- 递归计算行列式的函数 local function determinant(matrix) local n, det, sign, row, sub_matrix n = #matrix det = 0 -- 二阶行列式的边界条件 if n == 2 then return matrix[1][1] * matrix[2][2] - matrix[1][2] * matrix[2][1] end -- 递归计算行列式 for j = 1, n do sub_matrix = {} for i = 2, n do row = {} for k = 1, n do if k ~= j then table.insert(row, matrix[i][k]) end end table.insert(sub_matrix, row) end sign = (-1) ^ (1 + j) det = det + sign * matrix[1][j] * determinant(sub_matrix) end return fn(det) end return determinant(matrix) end calc_methods["hls"] = hls methods_desc["hls"] = "计算行列式" -- 取余函数 local function remainder(x, y) -- 使用math.fmod函数计算余数 local result = math.fmod(x, y) -- 如果x是负数,math.fmod会返回负数,需要调整为正数 if result < 0 then result = result + y end return fn(result) end calc_methods["mod"] = remainder methods_desc["mod"] = "求余函数" -- 连续自然数平方和(从1开始) local function sum_of_squares(n) -- 检查参数 if type(n) ~= "number" or n < 1 or n ~= floor(n) then return "错误:参数必须为正整数" end -- 计算平方和 local result = n * (n + 1) * (2 * n + 1) / 6 return fn(result) end calc_methods["sq"] = sum_of_squares methods_desc["sq"] = "连续自然数平方和(从1开始)" -- 连续自然数立方和(从1开始) local function sum_of_cubes(n) -- 检查参数 if type(n) ~= "number" or n < 1 or n ~= floor(n) then return "错误:参数必须为正整数" end -- 计算立方和 local result = (n * (n + 1)) ^ 2 / 4 return fn(result) end calc_methods["cb"] = sum_of_cubes methods_desc["cb"] = "连续自然数立方和(从1开始)" -- 连续自然数4次方之和(从1开始) local function sum_of_fourth_powers(n) -- 检查参数 if type(n) ~= "number" or n < 1 or n ~= floor(n) then return "错误:参数必须为正整数" end -- 计算4次方和 local result = n * (n + 1) * (2 * n + 1) * (3 * n ^ 2 + 3 * n - 1) / 30 return fn(result) end calc_methods["fp"] = sum_of_fourth_powers methods_desc["fp"] = "连续自然数4次方之和(从1开始)" -- 前n个奇数的平方和 local function sum_of_odd_squares(n) -- 检查参数 if type(n) ~= "number" or n < 1 or n ~= floor(n) then return "错误:参数必须为正整数" end -- 计算平方和 local result = n * (4 * n ^ 2 - 1) / 3 return fn(result) end calc_methods["osq"] = sum_of_odd_squares methods_desc["osq"] = "前n个奇数的平方和" -- 前n个偶数的平方和 local function sum_of_even_squares(n) -- 检查参数 if type(n) ~= "number" or n < 1 or n ~= floor(n) then return "错误:参数必须为正整数" end -- 计算平方和 local result = 2 * n * (n + 1) * (2 * n + 1) / 3 return fn(result) end calc_methods["esq"] = sum_of_even_squares methods_desc["esq"] = "前n个偶数的平方和" -- 前n个奇数的立方和 local function sum_of_odd_cubes(n) -- 检查参数 if type(n) ~= "number" or n < 1 or n ~= floor(n) then return "错误:参数必须为正整数" end -- 计算立方和 local result = n ^ 2 * (2 * n ^ 2 - 1) return fn(result) end calc_methods["ocb"] = sum_of_odd_cubes methods_desc["ocb"] = "前n个奇数的立方和" -- 前n个偶数的立方和 local function sum_of_even_cubes(n) -- 检查参数 if type(n) ~= "number" or n < 1 or n ~= floor(n) then return "错误:参数必须为正整数" end -- 计算立方和 local result = 2 * (n * (n + 1)) ^ 2 return fn(result) end calc_methods["ecb"] = sum_of_even_cubes methods_desc["ecb"] = "前n个偶数的立方和" -- 前n个奇数的4次方之和 local function sum_of_odd_fourth_powers(n) -- 检查参数 if type(n) ~= "number" or n < 1 or n ~= floor(n) then return "错误:参数必须为正整数" end -- 计算4次方和 local result = (48 * n ^ 5 - 40 * n ^ 3 + 7 * n) / 15 return fn(result) end calc_methods["ofp"] = sum_of_odd_fourth_powers methods_desc["ofp"] = "前n个奇数的4次方之和" -- 前n个偶数的4次方之和 local function sum_of_even_fourth_powers(n) -- 检查参数 if type(n) ~= "number" or n < 1 or n ~= floor(n) then return "错误:参数必须为正整数" end -- 计算4次方和 local result = 8 * n * (n + 1) * (2 * n + 1) * (3 * n ^ 2 + 3 * n - 1) / 15 return fn(result) end calc_methods["efp"] = sum_of_even_fourth_powers methods_desc["efp"] = "前n个偶数的4次方之和" -- 圆的标准方程的表达式优化 local function CircleStandardEquation(h, k, r_squared) local standardEquation if h == 0 then if k > 0 then standardEquation = "x²+(y-" .. k .. ")²=" .. r_squared elseif k == 0 then standardEquation = "x²+y²=" .. r_squared else standardEquation = "x²+(y+" .. -k .. ")²=" .. r_squared end elseif k == 0 then if h > 0 then standardEquation = "(x-" .. h .. ")²+y²=" .. r_squared elseif h == 0 then standardEquation = "x²+y²=" .. r_squared else standardEquation = "(x+" .. -h .. ")²+y²=" .. r_squared end else if h > 0 and k > 0 then standardEquation = "(x-" .. h .. ")²+(y-" .. k .. ")²=" .. r_squared elseif h > 0 and k < 0 then standardEquation = "(x-" .. h .. ")²+(y+" .. -k .. ")²=" .. r_squared elseif h < 0 and k > 0 then standardEquation = "(x+" .. -h .. ")²+(y-" .. k .. ")²=" .. r_squared else standardEquation = "(x+" .. -h .. ")²+(y+" .. -k .. ")²=" .. r_squared end end return standardEquation end -- 圆的一般方程表达式优化 local function CircleGeneralEquation(D, E, F) local generalEquation = "x²+y²" -- 处理D项 if D ~= 0 then if D == -1 then generalEquation = generalEquation .. "-x" elseif D == 1 then generalEquation = generalEquation .. "+x" elseif D > 0 then generalEquation = generalEquation .. "+" .. D .. "x" else generalEquation = generalEquation .. "-" .. -D .. "x" end end -- 处理E项 if E ~= 0 then if E == -1 then generalEquation = generalEquation .. "-y" elseif E == 1 then generalEquation = generalEquation .. "+y" elseif E > 0 then generalEquation = generalEquation .. "+" .. E .. "y" else generalEquation = generalEquation .. "-" .. -E .. "y" end end -- 处理F项 if F ~= 0 then if F > 0 then generalEquation = generalEquation .. "+" .. F .. "=0" else generalEquation = generalEquation .. "-" .. -F .. "=0" end end return generalEquation end -- 直线方程(斜截式)表达式优化 local function LineEquation(x1, y1, k) local equation, b -- 特殊情况 if k == nil then return "x=" .. x1 else equation = "y=" end if k == 0 then equation = equation .. y1 return equation end -- 计算截距b b = fn(y1 - k * x1) -- 优化k的表示 if k == -1 then equation = equation .. "-x" elseif k == 1 then equation = equation .. "x" else if k > 0 then equation = equation .. k .. "x" else equation = equation .. "-" .. -k .. "x" end end -- 优化b的表示 if b ~= 0 then if b > 0 then equation = equation .. "+" .. b else equation = equation .. "-" .. -b end end return equation end -- 直线方程(一般式)表达式优化 local function LineGeneralEquation(A, B, C) -- 检查参数正确性 if A == 0 and B == 0 then return "错误:直线方程系数A和B不能同时为0" end -- 求最大公约数,简化系数 local s, result s = gcd_multiple(math.abs(A), math.abs(B), math.abs(C)) if A < 0 then A = -A B = -B C = -C end A = fn(A / s) B = fn(B / s) C = fn(C / s) if A ~= 0 and B == 0 and C == 0 then result = "x=0" end if A ~= 0 and B == 0 and C ~= 0 then result = "x=" .. fn(-C / A) end if A == 0 and B ~= 0 and C == 0 then result = "y=0" end if A == 0 and B ~= 0 and C ~= 0 then result = "y=" .. fn(-C / B) end if A ~= 0 and B ~= 0 then if A == 1 then result = "x" else result = A .. "x" end if B == 1 then result = result .. "+y" elseif B == -1 then result = result .. "-y" elseif B > 0 then result = result .. "+" .. B .. "y" else result = result .. "-" .. -B .. "y" end if C ~= 0 then if C > 0 then result = result .. "+" .. C .. "=0" else result = result .. "-" .. -C .. "=0" end else result = result .. "=0" end end return result end -- 二次函数表达式优化 local function QuadraticEquation(a, b, c) local result = "y=" -- 格式化a的值 if a ~= 0 then if a == 1 then result = result .. "x²" elseif a == -1 then result = result .. "-x²" else result = result .. a .. "x²" end end -- 格式化b的值 if b ~= 0 then if b == 1 then result = result .. "+x" elseif b == -1 then result = result .. "-x" elseif b > 0 then result = result .. "+" .. b .. "x" else result = result .. "-" .. -b .. "x" end end -- 格式化c的值 if c ~= 0 then if c > 0 then result = result .. "+" .. c else result = result .. "-" .. -c end end return result end -- 已知正多边形边数n和边长a,计算正多边形面积 local function calculateRegularPolygonArea(n, a) -- 检查参数正确性 if type(n) ~= "number" or type(a) ~= "number" or n ~= floor(n) or n < 1 or a <= 0 then return "错误:边数n必须为正整数,边长a必须为正数" end -- 计算正多边形的面积 local s = (n * a ^ 2) / (4 * math.tan(math.pi / n)) return fn(s) end calc_methods["zdbx"] = calculateRegularPolygonArea methods_desc["zdbx"] = "已知边数n与边长a计算正多边形面积" -- 已知等比数列的首项a₁,公比q,求指定的前n项和 local function geometricSeriesSum(a1, q, n) -- 检查参数正确性 if type(a1) ~= "number" or type(q) ~= "number" or type(n) ~= "number" or n ~= floor(n) or n < 1 then return "错误:a₁、q、n必须为数字且n是正整数" end -- 计算前n项和 if a1 == 0 then return 0 elseif q == 0 and a1 ~= 0 then return a1 elseif q == 1 then return a1 * n else local s = a1 * (1 - q ^ n) / (1 - q) return fn(s) end end calc_methods["dbsl"] = geometricSeriesSum methods_desc["dbsl"] = "已知等比数列的首项a₁,公比q,求指定的前n项和" -- 已知等差数列的首项a₁,公差d,求指定的前n项和 local function ArithmeticSeriesSum(a1, d, n) -- 检查参数正确性 if type(a1) ~= "number" or type(d) ~= "number" or type(n) ~= "number" or n ~= floor(n) or n < 1 then return "错误:a₁、d、n必须为数字且n是正整数" end -- 计算前n项和 if a1 == 0 and d == 0 then return 0 elseif a1 ~= 0 and d == 0 then return a1 * n else local s = n * a1 + n * (n - 1) * d / 2 return fn(s) end end calc_methods["dcsl"] = ArithmeticSeriesSum methods_desc["dcsl"] = "已知等差数列的首项a₁,公差d,求指定的前n项和" -- 已知数列中任意两项aᵢ、aₖ,求通项公式 -- 对应项数分别为i、k -- b=0为等差数列,b=1为等比数列 local function findSequenceFormula(i, ai, k, ak, b) -- 检查参数正确性 if type(i) ~= "number" or i ~= floor(i) or i < 1 or type(k) ~= "number" or k ~= floor(k) or k < 1 then return "错误:i 和 k 必须是正整数" end if ai == ak and i == k then return "错误:aᵢ、aₖ 和对应的项数不能同时相等" elseif ai ~= ak and i == k then return "错误:同一项数对应不同的项值" end -- 计算等差数列的通项公式 local function arithmeticSequence(i, ai, k, ak) local d, a1, s d = fn((ak - ai) / (k - i)) a1 = ai - (i - 1) * d s = fn(a1 - d) if d == 0 then return "aₙ=" .. a1 elseif d == 1 then if s == 0 then return "aₙ=n" elseif s > 0 then return "aₙ=n+" .. s else return "aₙ=n-" .. -s end elseif d == -1 then if s == 0 then return "aₙ=-n" elseif s > 0 then return "aₙ=-n+" .. s else return "aₙ=-n-" .. -s end else if s == 0 then return "aₙ=" .. d .. "n" elseif s > 0 then return "aₙ=" .. d .. "n+" .. s else return "aₙ=" .. d .. "n-" .. -s end end end -- 计算等比数列的通项公式 local function geometricSequence(i, ai, k, ak) if ai == 0 or ak == 0 then return "错误:等比数列中不能有0项" end local s, q, n, a1 s = fn(ak / ai) n = fn(k - i) if s < 0 and n % 2 == 0 then return "无法求解通项公式" end q = fn(nth_root(s, n)) a1 = fn(ai / (q ^ (i - 1))) if a1 == q then if q == 1 then return "aₙ=" .. q elseif q > 0 then return "aₙ=" .. q .. "ⁿ" elseif q < 0 then return "aₙ=(" .. q .. ")ⁿ" end elseif a1 == -q then if q == 1 then return "aₙ=-" .. q elseif q == -1 then return "aₙ=(" .. q .. ")ⁿ⁻¹" elseif q > 0 then return "aₙ=-" .. q .. "ⁿ" else return "aₙ=-(" .. q .. ")ⁿ" end else if q > 0 then if a1 == 1 then return "aₙ=" .. q .. "ⁿ⁻¹" elseif a1 == -1 then return "aₙ=-" .. q .. "ⁿ⁻¹" else return "aₙ=" .. a1 .. "×" .. q .. "ⁿ⁻¹" end else if a1 == 1 then return "aₙ=(" .. q .. ")ⁿ⁻¹" elseif a1 == -1 then return "aₙ=-(" .. q .. ")ⁿ⁻¹" else return "aₙ=" .. a1 .. "×(" .. q .. ")ⁿ⁻¹" end end end end -- 根据b值返回通项公式 if b == 0 then return arithmeticSequence(i, ai, k, ak) elseif b == 1 then return geometricSequence(i, ai, k, ak) else return "错误:参数b必须是0或1" end end calc_methods["tx"] = findSequenceFormula methods_desc["tx"] = "已知数列的任意两项aᵢ、aₖ及对应的项数i、k,求其通项公式" -- 已知圆心坐标(h,k)和半径r,求圆的标准方程和一般方程 local function CircleEquationsxr(h, k, r) -- 检查半径是否为正数 if r <= 0 then return "错误:半径必须大于0" end -- 圆的标准方程 local r_squared, se, ge, D, E, F r_squared = fn(r ^ 2) se = CircleStandardEquation(h, k, r_squared) -- 圆的一般方程 D = fn(-2 * h) E = fn(-2 * k) F = fn(h ^ 2 + k ^ 2 - r ^ 2) ge = CircleGeneralEquation(D, E, F) -- 返回两个方程 return "标准方程: " .. se .. "\n一般方程: " .. ge end calc_methods["cexr"] = CircleEquationsxr methods_desc["cexr"] = "已知圆心坐标和半径求圆的方程" -- 已知圆心坐标(h,k)和圆上不同两点(x₁,y₁),(x₂,y₂),求圆的标准方程和一般方程 local function CircleEquationsxl(h, k, x1, y1, x2, y2) -- 检查三个坐标中是否有任意两个点坐标完全相同 if (x1 == x2 and y1 == y2) or (x1 == h and y1 == k) or (x2 == h and y2 == k) then return "错误:三个坐标中不能有任意两个点坐标完全相同" end local distance1, distance2, r, r_squared, se, ge, D, E, F -- 计算两点到圆心的距离,并检查是否相等 distance1 = math.sqrt((x1 - h) ^ 2 + (y1 - k) ^ 2) distance2 = math.sqrt((x2 - h) ^ 2 + (y2 - k) ^ 2) if distance1 ~= distance2 then return "错误:给定的圆心坐标和两个点无法构成圆" end -- 圆的标准方程 r = distance1 r_squared = fn(r ^ 2) se = CircleStandardEquation(h, k, r_squared) -- 圆的一般方程 D = fn(-2 * h) E = fn(-2 * k) F = fn(h ^ 2 + k ^ 2 - r_squared) ge = CircleGeneralEquation(D, E, F) -- 返回两个方程 return "标准方程: " .. se .. "\n一般方程: " .. ge end calc_methods["cexl"] = CircleEquationsxl methods_desc["cexl"] = "已知圆心和圆上不同两点的坐标求圆方程" -- 已知不共线的三点(x₁,y₁),(x₂,y₂),(x₃,y₃),求过它们的圆的方程 local function CircleEquationssd(x1, y1, x2, y2, x3, y3) local determinant, A, B, detA, detAD, detAE, detAF, D, E, F, ge, se, r_squared, h, k -- 检查三个点是否共线 determinant = x1 * (y2 - y3) + x2 * (y3 - y1) + x3 * (y1 - y2) if determinant == 0 then return "错误:三个点共线或重合,无法构成圆" end -- 构建系数矩阵A和常数矩阵B A = { { x1, y1, 1 }, { x2, y2, 1 }, { x3, y3, 1 } } B = { (-x1 ^ 2 - y1 ^ 2), (-x2 ^ 2 - y2 ^ 2), (-x3 ^ 2 - y3 ^ 2) } -- 计算系数矩阵A的行列式detA detA = hls(A[1][1], A[1][2], A[1][3], A[2][1], A[2][2], A[2][3], A[3][1], A[3][2], A[3][3]) -- 计算D、E、F的行列式 detAD = hls(B[1], A[1][2], A[1][3], B[2], A[2][2], A[2][3], B[3], A[3][2], A[3][3]) detAE = hls(A[1][1], B[1], A[1][3], A[2][1], B[2], A[2][3], A[3][1], B[3], A[3][3]) detAF = hls(A[1][1], A[1][2], B[1], A[2][1], A[2][2], B[2], A[3][1], A[3][2], B[3]) -- 计算系数D、E、F D = fn(detAD / detA) E = fn(detAE / detA) F = fn(detAF / detA) -- 圆的一般方程 ge = CircleGeneralEquation(D, E, F) -- 圆的标准方程 h = fn(-D / 2) k = fn(-E / 2) r_squared = fn(h ^ 2 + k ^ 2 - F) se = CircleStandardEquation(h, k, r_squared) -- 返回两个方程 return "标准方程: " .. se .. "\n一般方程: " .. ge end calc_methods["cesd"] = CircleEquationssd methods_desc["cesd"] = "已知圆上不同三点的坐标,求圆方程" -- 求解一元一次方程:ax+b=0 local function solveLinearEquation(a, b) -- 检查a是否为0,因为如果a为0,方程将不再是一元一次方程 if a == 0 then if b == 0 then return "方程有无数解" else return "方程无解" end else -- 计算x的值 local x = fn(-b / a) return "x=" .. x end end calc_methods["yyyc"] = solveLinearEquation methods_desc["yyyc"] = "求解一元一次方程" -- 求解二元一次方程组:ax+by=e,cx+dy=f local function solveLinearSystem(a, b, c, d, e, f) local D, x, y -- 计算行列式D D = a * d - b * c -- 检查方程组是否有解 if D == 0 then if (a * f - c * e) == 0 and (b * e - d * f) == 0 then return "方程组有无穷多解" else return "方程组无解" end end -- 计算x和y x = fn((d * e - b * f) / D) y = fn((a * f - c * e) / D) -- 返回解的字符串表示 return "x=" .. x .. "\ny=" .. y end calc_methods["eyyc"] = solveLinearSystem methods_desc["eyyc"] = "求解二元一次方程组ax+by=e,cx+dy=f" -- 点斜法求解一次函数解析式 -- 定义函数,输入斜率k和点的坐标(x₁, y₁) local function pointSlopeForm(k, x1, y1) local le = LineEquation(x1, y1, k) return "直线方程: " .. le end calc_methods["dxf"] = pointSlopeForm methods_desc["dxf"] = "点斜法求解一次函数解析式" -- 两点法求解一次函数解析式 -- 定义函数,输入两点坐标(x₁, y₁)、(x₂,y₂) local function twoPointsForm(x1, y1, x2, y2) -- 检查两点是否相同 if x1 == x2 and y1 == y2 then return "错误:两点坐标完全相同,无法确定直线方程" end local k, le -- 计算斜率k if x1 == x2 then k = nil else k = (y2 - y1) / (x2 - x1) k = fn(k) end le = LineEquation(x1, y1, k) return "直线方程: " .. le end calc_methods["ldf"] = twoPointsForm methods_desc["ldf"] = "两点法求解一次函数解析式" -- 求解一元二次方程ax²+bx+c=0 local function solveQuadraticEquation(a, b, c) -- 检查参数正确性 if type(a) ~= "number" or type(b) ~= "number" or type(c) ~= "number" then return "错误:系数必须是数字" end if a == 0 then return "错误:二次项系数不能为0" end local Delta, x1, x2, P, Q Delta = b ^ 2 - 4 * a * c P = fn(-b / (2 * a)) if Delta == 0 then x1 = P return "x₁=x₂=" .. x1 elseif Delta > 0 then Q = fn(math.sqrt(Delta) / (2 * a)) x1 = P + Q x2 = P - Q else Q = fn(math.sqrt(-Delta) / (2 * a)) if P == 0 then if Q == 1 then x1 = "i" x2 = "-i" elseif Q == -1 then x1 = "-i" x2 = "i" else x1 = Q .. "i" x2 = -Q .. "i" end else if Q == 1 then x1 = P .. "+i" x2 = P .. "-i" elseif Q == -1 then x1 = P .. "-i" x2 = P .. "+i" elseif Q > 0 then x1 = P .. "+" .. Q .. "i" x2 = P .. "-" .. Q .. "i" else x1 = P .. "-" .. -Q .. "i" x2 = P .. "+" .. -Q .. "i" end end end return "x₁=" .. x1 .. "\nx₂=" .. x2 end calc_methods["yyec"] = solveQuadraticEquation methods_desc["yyec"] = "求解一元二次方程" -- 求解一元三次方程ax³+bx²+cx+d=0 local function solveCubicEquation(a, b, c, d) -- 检查参数正确性 if type(a) ~= "number" or type(b) ~= "number" or type(c) ~= "number" or type(d) ~= "number" then return "错误:系数必须是数字" end if a == 0 then return "错误:系数a不能为零" end -- 计算重根判别式 local A, B, C, Delta A = b ^ 2 - 3 * a * c B = b * c - 9 * a * d C = c ^ 2 - 3 * b * d -- 计算总判别式 Delta = B ^ 2 - 4 * A * C -- 根据盛金公式进行求解 -- 情况1:A = B = 0,方程有一个三重实根 if A == 0 and B == 0 then local x = fn(-b / (3 * a)) return "x₁=x₂=x₃=" .. x -- 情况2:Delta > 0,方程有一个实根和一对共轭虚根 elseif Delta > 0 then local Y1, Y2, y1, y2, x1, x2, x3, P, Q Y1 = A * b + 3 * a * (-B + math.sqrt(Delta)) / 2 Y2 = A * b + 3 * a * (-B - math.sqrt(Delta)) / 2 y1 = nth_root(Y1, 3) y2 = nth_root(Y2, 3) x1 = fn((-b - y1 - y2) / (3 * a)) P = fn((-b + 0.5 * (y1 + y2)) / (3 * a)) Q = fn((0.5 * math.sqrt(3) * (y1 - y2)) / (3 * a)) if P == 0 then if Q == 1 then x2 = "i" x3 = "-i" elseif Q == -1 then x2 = "-i" x3 = "i" else x2 = Q .. "i" x3 = -Q .. "i" end elseif P ~= 0 and Q == 1 then x2 = P .. "+i" x3 = P .. "-i" elseif P ~= 0 and Q == -1 then x2 = P .. "-i" x3 = P .. "+i" elseif P ~= 0 and Q > 0 then x2 = P .. "+" .. Q .. "i" x3 = P .. "-" .. Q .. "i" elseif P ~= 0 and Q < 0 then x2 = P .. "-" .. -Q .. "i" x3 = P .. "+" .. -Q .. "i" end return "x₁=" .. x1 .. "\nx₂=" .. x2 .. "\nx₃=" .. x3 -- 情况3:Delta = 0,方程有三个实根,其中有一个两重根 elseif Delta == 0 and A ~= 0 then local K, x1, x2 K = B / A x1 = fn(-b / a + K) x2 = fn(-0.5 * K) return "x₁=" .. x1 .. "\nx₂=x₃=" .. x2 elseif Delta < 0 and A > 0 then -- 情况4:Delta < 0,方程有三个不相等的实根 local T, M, S, R, x1, x2, x3 T = (2 * A * b - 3 * a * B) / (2 * math.sqrt(A ^ 3)) M = acos(T) S = cos(M / 3) R = sin(M / 3) x1 = fn((-b - 2 * math.sqrt(A) * S) / (3 * a)) x2 = fn((-b + math.sqrt(A) * (S + math.sqrt(3) * R)) / (3 * a)) x3 = fn((-b + math.sqrt(A) * (S - math.sqrt(3) * R)) / (3 * a)) return "x₁=" .. x1 .. "\nx₂=" .. x2 .. "\nx₃=" .. x3 end end calc_methods["yysc1"] = solveCubicEquation methods_desc["yysc1"] = "求解一元三次方程" -- 求解一元四次方程ax⁴+bx³+cx²+dx+e=0 local function solveQuarticEquation(a, b, c, d, e) -- 检查参数正确性 if type(a) ~= "number" or type(b) ~= "number" or type(c) ~= "number" or type(d) ~= "number" or type(e) ~= "number" then return "错误:系数必须是数字" end if a == 0 then return "错误:系数a不能为零" end -- 计算重根判别式 local D, E, F, A, B, C, Delta D = 3 * b ^ 2 - 8 * a * c E = -b ^ 3 + 4 * a * b * c - 8 * a ^ 2 * d F = 3 * b ^ 4 + 16 * a ^ 2 * c ^ 2 - 16 * a * b ^ 2 * c + 16 * a ^ 2 * b * d - 64 * a ^ 3 * e A = D ^ 2 - 3 * F B = D * F - 9 * E ^ 2 C = F ^ 2 - 3 * D * E ^ 2 -- 计算总判别式 Delta = B ^ 2 - 4 * A * C -- 符号因子函数 local function sgn(x) if x == 0 then return 0 else return fn(math.abs(x) / x) end end -- 根据天珩公式求解四次方程 -- 情况1:当D=E=F=0时,方程有一个四重实根 if D == 0 and E == 0 and F == 0 then local x x = fn(-b / (4 * a)) return "x₁=x₂=x₃=x₄=" .. x end -- 情况2:当DEF≠0,A=B=C=0时,方程有四个实根,其中有一个三重根 if (D * E * F ~= 0) and (A == 0 and B == 0 and C == 0) then local x1, x2 x1 = fn((-b * D + 9 * E) / (4 * a * D)) x2 = fn((-b * D - 3 * E) / (4 * a * D)) return "x₁=" .. x1 .. "\nx₂=x₃=x₄=" .. x2 end -- 情况3:当E=F=0,D≠0时,方程有两对二重根;若D>0,根为实数;若D<0,根为虚数 if E == 0 and F == 0 and D ~= 0 then local x1, x2, P, Q if D > 0 then x1 = fn((-b + math.sqrt(D)) / (4 * a)) x2 = fn((-b - math.sqrt(D)) / (4 * a)) else P = fn(-b / (4 * a)) Q = fn(math.sqrt(-D) / (4 * a)) if P == 0 then if Q == 1 then x1 = "i" x2 = "-i" elseif Q == -1 then x1 = "-i" x2 = "i" else x1 = Q .. "i" x2 = -Q .. "i" end else if Q == 1 then x1 = P .. "+i" x2 = P .. "-i" elseif Q == -1 then x1 = P .. "-i" x2 = P .. "+i" elseif Q > 0 then x1 = P .. "+" .. Q .. "i" x2 = P .. "-" .. Q .. "i" else x1 = P .. "-" .. -Q .. "i" x2 = P .. "+" .. -Q .. "i" end end end return "x₁=x₂=" .. x1 .. "\nx₃=x₄=" .. x2 end -- 情况4:当ABC≠0,Δ=0时,方程有一对二重实根; -- 若AB>0,则其余两根为不等实根;若AB<0,则其余两根为共轭虚根 if (A * B * C ~= 0) and (Delta == 0) then local P, Q, R, x1, x2, x3 P = -b / (4 * a) Q = 2 * A * E / (4 * a * B) x1 = fn(P - Q) if A * B > 0 then R = math.sqrt(2 * B / A) / (4 * a) x2 = fn(P + Q + R) x3 = fn(P + Q - R) else R = fn(math.sqrt(-2 * B / A) / (4 * a)) if (P + Q) == 0 then if R == 1 then x2 = "i" x3 = "-i" elseif R == -1 then x2 = "-i" x3 = "i" else x2 = R .. "i" x3 = -R .. "i" end else if R == 1 then x2 = fn(P + Q) .. "+i" x3 = fn(P + Q) .. "-i" elseif R == -1 then x2 = fn(P + Q) .. "-i" x3 = fn(P + Q) .. "+i" elseif R > 0 then x2 = fn(P + Q) .. "+" .. R .. "i" x3 = fn(P + Q) .. "-" .. R .. "i" else x2 = fn(P + Q) .. "-" .. -R .. "i" x3 = fn(P + Q) .. "+" .. -R .. "i" end end end return "x₁=x₂=" .. x1 .. "\nx₃=" .. x2 .. "\nx₄=" .. x3 end -- 情况5:当Δ>0时,方程有两个不等实根和一对共轭虚根 if Delta > 0 then local z, z1, z2, z3, x1, x2, x3, x4, P, Q, R1, R2 z1 = A * D + 3 * ((-B + math.sqrt(Delta)) / 2) z2 = A * D + 3 * ((-B - math.sqrt(Delta)) / 2) z3 = nth_root(z1, 3) + nth_root(z2, 3) z = D ^ 2 - D * z3 + z3 ^ 2 - 3 * A P = -b / (4 * a) Q = sgn(E) * math.sqrt((D + z3) / 3) / (4 * a) R1 = math.sqrt((2 * D - z3 + 2 * math.sqrt(z)) / 3) / (4 * a) R2 = fn(math.sqrt((-2 * D + z3 + 2 * math.sqrt(z)) / 3) / (4 * a)) x1 = fn(P + Q + R1) x2 = fn(P + Q - R1) if (P - Q) == 0 then if R2 == 1 then x3 = "i" x4 = "-i" elseif R2 == -1 then x3 = "-i" x4 = "i" else x3 = R2 .. "i" x4 = -R2 .. "i" end else if R2 == 1 then x3 = fn(P - Q) .. "+i" x4 = fn(P - Q) .. "-i" elseif R2 == -1 then x3 = fn(P - Q) .. "-i" x4 = fn(P - Q) .. "+i" elseif R2 > 0 then x3 = fn(P - Q) .. "+" .. R2 .. "i" x4 = fn(P - Q) .. "-" .. R2 .. "i" else x3 = fn(P - Q) .. "-" .. -R2 .. "i" x4 = fn(P - Q) .. "+" .. -R2 .. "i" end end return "x₁=" .. x1 .. "\nx₂=" .. x2 .. "\nx₃=" .. x3 .. "\nx₄=" .. x4 end -- 情况6:当Δ<0时,若D与F均为正数,则方程有四个不等实根;否则方程有两对不等共轭虚根 if Delta < 0 then local T, M, N, O, y1, y2, y3, x1, x2, x3, x4, P, Q1, Q2, Q3 T = (3 * B - 2 * A * D) / (2 * A * math.sqrt(A)) M = acos(T) N = cos(M / 3) O = sin(M / 3) y1 = (D - 2 * math.sqrt(A) * N) / 3 y2 = (D + math.sqrt(A) * (N + math.sqrt(3) * O)) / 3 y3 = (D + math.sqrt(A) * (N - math.sqrt(3) * O)) / 3 -- 情况6.1:若E=0,D>0,F>0,方程有四实根 if E == 0 and D > 0 and F > 0 then x1 = fn((-b + math.sqrt(D + 2 * math.sqrt(F))) / (4 * a)) x2 = fn((-b - math.sqrt(D + 2 * math.sqrt(F))) / (4 * a)) x3 = fn((-b + math.sqrt(D - 2 * math.sqrt(F))) / (4 * a)) x4 = fn((-b - math.sqrt(D - 2 * math.sqrt(F))) / (4 * a)) -- 情况6.2:若E=0,D<0,F>0,方程有两对共轭虚根 elseif E == 0 and D < 0 and F > 0 then P = fn(-b / (4 * a)) Q1 = fn(math.sqrt(-D + 2 * math.sqrt(F)) / (4 * a)) Q2 = fn(math.sqrt(-D - 2 * math.sqrt(F)) / (4 * a)) if P == 0 then if Q1 == 1 then x1 = "i" x2 = "-i" elseif Q1 == -1 then x1 = "-i" x2 = "i" else x1 = Q1 .. "i" x2 = -Q1 .. "i" end if Q2 == 1 then x3 = "i" x4 = "-i" elseif Q2 == -1 then x3 = "-i" x4 = "i" else x3 = Q2 .. "i" x4 = -Q2 .. "i" end else if Q1 == 1 then x1 = P .. "+i" x2 = P .. "-i" elseif Q1 == -1 then x1 = P .. "-i" x2 = P .. "+i" elseif Q1 > 0 then x1 = P .. "+" .. Q1 .. "i" x2 = P .. "-" .. Q1 .. "i" else x1 = P .. "-" .. -Q1 .. "i" x2 = P .. "+" .. -Q1 .. "i" end if Q2 == 1 then x3 = P .. "+i" x4 = P .. "-i" elseif Q2 == -1 then x3 = P .. "-i" x4 = P .. "+i" elseif Q2 > 0 then x3 = P .. "+" .. Q2 .. "i" x4 = P .. "-" .. Q2 .. "i" else x3 = P .. "-" .. -Q2 .. "i" x4 = P .. "+" .. -Q2 .. "i" end end -- 情况6.3:若E=0,F<0,方程有两对共轭虚根 elseif E == 0 and F < 0 then P = -b / (4 * a) Q1 = math.sqrt(2 * D + 2 * math.sqrt(A - F)) / (8 * a) Q2 = fn(math.sqrt(-2 * D + 2 * math.sqrt(A - F)) / (8 * a)) if (P + Q1) == 0 then if Q2 == 1 then x1 = "i" x2 = "-i" elseif Q2 == -1 then x1 = "-i" x2 = "i" else x1 = Q2 .. "i" x2 = -Q2 .. "i" end else if Q2 == 1 then x1 = fn(P + Q1) .. "+i" x2 = fn(P + Q1) .. "-i" elseif Q2 == -1 then x1 = fn(P + Q1) .. "-i" x2 = fn(P + Q1) .. "+i" elseif Q2 > 0 then x1 = fn(P + Q1) .. "+" .. Q2 .. "i" x2 = fn(P + Q1) .. "-" .. Q2 .. "i" else x1 = fn(P + Q1) .. "-" .. -Q2 .. "i" x2 = fn(P + Q1) .. "+" .. -Q2 .. "i" end end if (P - Q1) == 0 then if Q2 == 1 then x3 = "i" x4 = "-i" elseif Q2 == -1 then x3 = "-i" x4 = "i" else x3 = Q2 .. "i" x4 = -Q2 .. "i" end else if Q2 == 1 then x3 = fn(P - Q1) .. "+i" x4 = fn(P - Q1) .. "-i" elseif Q2 == -1 then x3 = fn(P - Q1) .. "-i" x4 = fn(P - Q1) .. "+i" elseif Q2 > 0 then x3 = fn(P - Q1) .. "+" .. Q2 .. "i" x4 = fn(P - Q1) .. "-" .. Q2 .. "i" else x3 = fn(P - Q1) .. "-" .. -Q2 .. "i" x4 = fn(P - Q1) .. "+" .. -Q2 .. "i" end end -- 情况6.4:若E≠0,当D与F均为正时,方程有四实根;否则方程有两对共轭虚根 elseif E ~= 0 then if D > 0 and F > 0 then P = -b / (4 * a) Q1 = sgn(E) * math.sqrt(y1) / (4 * a) Q2 = (math.sqrt(y2) + math.sqrt(y3)) / (4 * a) Q3 = (math.sqrt(y2) - math.sqrt(y3)) / (4 * a) x1 = fn(P + Q1 + Q2) x2 = fn(P + Q1 - Q2) x3 = fn(P - Q1 + Q3) x4 = fn(P - Q1 - Q3) else P = -b / (4 * a) Q1 = math.sqrt(y2) / (4 * a) Q2 = sgn(E) * math.sqrt(-y1) / (4 * a) Q3 = math.sqrt(-y3) / (4 * a) if (P - Q1) == 0 then if (Q2 + Q3) == 1 then x1 = "i" x2 = "-i" elseif (Q2 + Q3) == -1 then x1 = "-i" x2 = "i" else x1 = fn(Q2 + Q3) .. "i" x2 = -fn(Q2 + Q3) .. "i" end else if fn(Q2 + Q3) == 1 then x1 = fn(P - Q1) .. "+i" x2 = fn(P - Q1) .. "-i" elseif fn(Q2 + Q3) == -1 then x1 = fn(P - Q1) .. "-i" x2 = fn(P - Q1) .. "+i" elseif fn(Q2 + Q3) > 0 then x1 = fn(P - Q1) .. "+" .. fn(Q2 + Q3) .. "i" x2 = fn(P - Q1) .. "-" .. fn(Q2 + Q3) .. "i" else x1 = fn(P - Q1) .. "-" .. -fn(Q2 + Q3) .. "i" x2 = fn(P - Q1) .. "+" .. -fn(Q2 + Q3) .. "i" end end if (P + Q1) == 0 then if fn(Q2 - Q3) == 1 then x3 = "i" x4 = "-i" elseif fn(Q2 - Q3) == -1 then x3 = "-i" x4 = "i" else x3 = fn(Q2 - Q3) .. "i" x4 = -fn(Q2 - Q3) .. "i" end else if fn(Q2 - Q3) == 1 then x3 = fn(P + Q1) .. "+i" x4 = fn(P + Q1) .. "-i" elseif fn(Q2 - Q3) == -1 then x3 = fn(P + Q1) .. "-i" x4 = fn(P + Q1) .. "+i" elseif fn(Q2 - Q3) > 0 then x3 = fn(P + Q1) .. "+" .. fn(Q2 - Q3) .. "i" x4 = fn(P + Q1) .. "-" .. fn(Q2 - Q3) .. "i" else x3 = fn(P + Q1) .. "-" .. -fn(Q2 - Q3) .. "i" x4 = fn(P + Q1) .. "+" .. -fn(Q2 - Q3) .. "i" end end end end return "x₁=" .. x1 .. "\nx₂=" .. x2 .. "\nx₃=" .. x3 .. "\nx₄=" .. x4 end end calc_methods["yysc2"] = solveQuarticEquation methods_desc["yysc2"] = "求解一元四次方程" -- 顶点式求解二次函数解析式:y=a(x-h)²+k -- (x₁,y₁)为顶点坐标,(x₂,y₂)为其函数图像上除顶点坐标外任意一点坐标 local function getQuadraticEquationdd(x1, y1, x2, y2) -- 检查两个点是否相同 if x1 == x2 or y1 == y2 then return "错误:两个点的横坐标不能相同" end local a, b, c, qe a = fn((y2 - y1) / (x2 - x1) ^ 2) b = fn(-2 * a * x1) c = fn(y1 + a * x1 ^ 2) qe = QuadraticEquation(a, b, c) return "二次函数解析式为:" .. qe end calc_methods["dds"] = getQuadraticEquationdd methods_desc["dds"] = "顶点式求解二次函数解析式" -- 一般式求解二次函数解析式 local function getQuadraticEquationy(x1, y1, x2, y2, x3, y3) local A, B, detA, detAx, detAy, detAz, a, b, c, qe, determinant -- 检查三个点是否共线 determinant = x1 * (y2 - y3) + x2 * (y3 - y1) + x3 * (y1 - y2) if determinant == 0 then return "错误:三个点共线或重合,无法求解二次函数解析式" end -- 构建方程组的系数矩阵和常数矩阵 A = { { x1 ^ 2, x1, 1 }, { x2 ^ 2, x2, 1 }, { x3 ^ 2, x3, 1 } } B = { (y1), (y2), (y3) } -- 计算系数矩阵A的行列式detA detA = hls(A[1][1], A[1][2], A[1][3], A[2][1], A[2][2], A[2][3], A[3][1], A[3][2], A[3][3]) -- 计算行列式detAx,detAy,detAz detAx = hls(B[1], A[1][2], A[1][3], B[2], A[2][2], A[2][3], B[3], A[3][2], A[3][3]) detAy = hls(A[1][1], B[1], A[1][3], A[2][1], B[2], A[2][3], A[3][1], B[3], A[3][3]) detAz = hls(A[1][1], A[1][2], B[1], A[2][1], A[2][2], B[2], A[3][1], A[3][2], B[3]) -- 计算系数a,b,c a = fn(detAx / detA) b = fn(detAy / detA) c = fn(detAz / detA) qe = QuadraticEquation(a, b, c) return "二次函数解析式为:" .. qe end calc_methods["ybs"] = getQuadraticEquationy methods_desc["ybs"] = "一般式求解二次函数解析式" -- 已知三角形的三边a、b、c,求三角形面积 local function calculateTriangleArea(a, b, c) -- 检查是否能构成三角形 if a + b <= c or a + c <= b or b + c <= a then return "错误:不能构成三角形" end local p, s -- 计算半周长 p = (a + b + c) / 2 -- 使用海伦公式计算面积 s = math.sqrt(p * (p - a) * (p - b) * (p - c)) return fn(s) end calc_methods["sjx1"] = calculateTriangleArea methods_desc["sjx1"] = "已知三角形的三边长a、b、c,求三角形面积" -- 已知三角形的三个顶点坐标(x₁, y₁),(x₂, y₂),(x₃, y₃),求三角形面积 local function calculateTriangleArea2(x1, y1, x2, y2, x3, y3) -- 检查参数正确性 if type(x1) ~= "number" or type(y1) ~= "number" or type(x2) ~= "number" or type(y2) ~= "number" or type(x3) ~= "number" or type(y3) ~= "number" then return "错误:参数必须是数字" end local determinant, s determinant = x1 * (y2 - y3) + x2 * (y3 - y1) + x3 * (y1 - y2) -- 检查是否能构成三角形 if determinant == 0 then return "错误:三个点重合或共线,不能构成三角形" end -- 计算三角形面积 s = fn(math.abs(determinant / 2)) return s end calc_methods["sjx2"] = calculateTriangleArea2 methods_desc["sjx2"] = "已知三角形的三个顶点坐标(x₁,y₁),(x₂,y₂),(x₃,y₃),求三角形面积" -- 已知一点(x₁, y₁)和直线方程Ax+By+C=0,求点到直线的距离和它关于直线的对称点坐标 local function dyzx1(x1, y1, A, B, C) -- 检查参数正确性 if type(x1) ~= "number" or type(y1) ~= "number" or type(A) ~= "number" or type(B) ~= "number" or type(C) ~= "number" then return "错误:参数必须是数字" end if A == 0 and B == 0 then return "错误:直线方程的系数不能同时为零" end local S, D, s, x, y -- 判断点是否在直线上 S = A * x1 + B * y1 + C if S == 0 then return "点在直线上,距离为0,无法求解对称点坐标" end -- 计算点到直线的距离 D = fn(math.abs(S) / math.sqrt(A ^ 2 + B ^ 2)) -- 计算对称点坐标 s = S / (A ^ 2 + B ^ 2) x = fn(x1 - 2 * A * s) y = fn(y1 - 2 * B * s) return "点到直线距离为" .. D .. "\n点关于直线的对称点坐标为(" .. x .. "," .. y .. ")" end calc_methods["dyzx1"] = dyzx1 methods_desc["dyzx1"] = "已知一点坐标(x₁, y₁)和直线方程Ax+By+C=0,求点到直线的距离及对称点坐标" -- 已知两点(x₁, y₁)和(x₂, y₂),求两点间的距离 local function ld1(x1, y1, x2, y2) -- 检查参数正确性 if type(x1) ~= "number" or type(y1) ~= "number" or type(x2) ~= "number" or type(y2) ~= "number" then return "错误:参数必须是数字" end -- 判断两点是否重合 if x1 == x2 and y1 == y2 then return "两点重合,距离为0" end -- 计算两点间的距离 local D = math.sqrt((x2 - x1) ^ 2 + (y2 - y1) ^ 2) return fn(D) end calc_methods["ld1"] = ld1 methods_desc["ld1"] = "已知两点坐标,求两点间的距离" -- 已知两点(x₁, y₁)和(x₂, y₂),求两点连线的垂直平分线方程 local function ld2(x1, y1, x2, y2) -- 检查参数正确性 if type(x1) ~= "number" or type(y1) ~= "number" or type(x2) ~= "number" or type(y2) ~= "number" then return "错误:参数必须是数字" end if x1 == x2 and y1 == y2 then return "错误:两点重合,无法求解垂直平分线方程" end local x3, y3, k, kl, se -- 两点所成线段的中点坐标 x3 = fn((x1 + x2) / 2) y3 = fn((y1 + y2) / 2) if x1 == x2 then k = nil kl = 0 else k = (y2 - y1) / (x2 - x1) if k == 0 then kl = nil else kl = -1 / k kl = fn(kl) end end se = LineEquation(x3, y3, kl) return "垂直平分线方程为:" .. se end calc_methods["ld2"] = ld2 methods_desc["ld2"] = "已知两点坐标,求两点间线段的垂直平分线方程" -- 已知两点P(x₁, y₁)和Q(x₂, y₂),求点P绕点Q旋转角度a(角度制)后的P'坐标 -- 逆时针时a为正,顺时针时a为负 local function ld3(x1, y1, x2, y2, a) -- 检查参数正确性 if type(x1) ~= "number" or type(y1) ~= "number" or type(x2) ~= "number" or type(y2) ~= "number" or type(a) ~= "number" then return "错误:参数必须是数字" end -- 计算旋转角度的弧度值 local a1, x, y a1 = rad(a) -- 计算旋转后的点坐标 x = fn(x2 + (x1 - x2) * cos(a1) - (y1 - y2) * sin(a1)) y = fn(y2 + (x1 - x2) * sin(a1) + (y1 - y2) * cos(a1)) return "点P(" .. x1 .. "," .. y1 .. ")绕点Q(" .. x2 .. "," .. y2 .. ")旋转" .. a .. "°后的P'坐标为(" .. x .. "," .. y .. ")" end calc_methods["ld3"] = ld3 methods_desc["ld3"] = "已知两点P(x₁, y₁)和Q(x₂, y₂),求点P绕点Q旋转角度a(角度制)后的P'坐标" -- 已知两条直线方程 A₁x+B₁y+C₁=0和 A₂x+B₂y+C₂=0,判断它们的位置关系 local function lines_relationship(A1, B1, C1, A2, B2, C2) -- 参数正确性检查 if (A1 == 0 and B1 == 0) or (A2 == 0 and B2 == 0) then return "错误:直线方程的系数不能同时为零" end local px, ch, D, x, y, k -- 判断两直线是否平行或重合的条件 px = (A1 * B2 == A2 * B1) and (A1 * C2 ~= A2 * C1) ch = (A1 * B2 == A2 * B1) and (C1 * B2 == C2 * B1) and (C1 * A2 == C2 * A1) -- 两直线重合 if ch then return "两直线重合,距离为0" -- 两直线平行但不重合,计算距离 elseif px then if B1 ~= B2 then k = math.max(B1, B2) / math.min(B1, B2) if B1 < B2 then A1 = A1 * k B1 = B1 * k C1 = C1 * k else C2 = C2 * k end end D = fn(math.abs(C2 - C1) / math.sqrt(A1 ^ 2 + B1 ^ 2)) return "两直线平行,距离为" .. D -- 两直线相交,计算交点坐标 else x = fn((B1 * C2 - B2 * C1) / (A1 * B2 - A2 * B1)) y = fn((C1 * A2 - C2 * A1) / (A1 * B2 - A2 * B1)) return "两直线相交,交点坐标为(" .. x .. "," .. y .. ")" end end calc_methods["lzx1"] = lines_relationship methods_desc["lzx1"] = "已知两直线方程A₁x+B₁y+C₁=0和A₂x+B₂y+C₂=0,判断它们的位置关系" -- 已知三角形的三边a、b、c,求内切圆半径和外接圆半径 local function triangle_circles(a, b, c) -- 参数正确性检查 if a <= 0 or b <= 0 or c <= 0 then return "错误:边长必须为正数" end -- 检查能否构成三角形 if a + b <= c or a + c <= b or b + c <= a then return "错误:给定的边长不能构成三角形" end local s, A, r, R -- 计算半周长 s = (a + b + c) / 2 -- 计算面积 A = math.sqrt(s * (s - a) * (s - b) * (s - c)) -- 计算内切圆半径 r = fn(A / s) -- 计算外接圆半径 R = fn((a * b * c) / (4 * A)) return "内切圆半径为" .. r .. "\n外接圆半径为" .. R end calc_methods["sjxy1"] = triangle_circles methods_desc["sjxy1"] = "已知三角形三边长,求内切圆半径和外接圆半径" -- 已知三角形三个顶点坐标(x₁,y₁),(x₂,y₂),(x₃,y₃),求其内切圆半径和外接圆半径 local function triangle_circles_by_points(x1, y1, x2, y2, x3, y3) -- 参数正确性检查 if type(x1) ~= "number" or type(y1) ~= "number" or type(x2) ~= "number" or type(y2) ~= "number" or type(x3) ~= "number" or type(y3) ~= "number" then return "错误:参数必须是数字" end local a, b, c -- 检查三个点是否共线 if x1 * (y2 - y3) + x2 * (y3 - y1) + x3 * (y1 - y2) == 0 then return "错误:三个点共线或重合,无法构成三角形" end -- 计算三边长 a = ld1(x1, y1, x2, y2) b = ld1(x2, y2, x3, y3) c = ld1(x1, y1, x3, y3) -- 调用已知三边长的函数计算内切圆半径和外接圆半径 return triangle_circles(a, b, c) end calc_methods["sjxy2"] = triangle_circles_by_points methods_desc["sjxy2"] = "已知三角形三个顶点坐标,求内切圆半径和外接圆半径" -- 已知三角形三个顶点坐标A(x₁,y₁),B(x₂,y₂),C(x₃,y₃),求其“心”的坐标 local function triangle_centers(x1, y1, x2, y2, x3, y3) -- 参数正确性检查 if type(x1) ~= "number" or type(y1) ~= "number" or type(x2) ~= "number" or type(y2) ~= "number" or type(x3) ~= "number" or type(y3) ~= "number" then return "错误:参数必须是数字" end local determinant, a, b, c, xg, yg, xn, yn, xw, yw, xc, yc, d1, s1, s2 -- 检查三个点是否共线 determinant = x1 * (y2 - y3) + x2 * (y3 - y1) + x3 * (y1 - y2) if determinant == 0 then return "错误:三个点共线或重合,无法构成三角形" end -- 计算三边长 a = ld1(x2, y2, x3, y3) b = ld1(x1, y1, x3, y3) c = ld1(x1, y1, x2, y2) -- 计算重心坐标 xg = fn((x1 + x2 + x3) / 3) yg = fn((y1 + y2 + y3) / 3) -- 计算内心坐标 xn = fn((a * x1 + b * x2 + c * x3) / (a + b + c)) yn = fn((a * y1 + b * y2 + c * y3) / (a + b + c)) -- 计算外心坐标 d1 = 2 * determinant xw = fn(((x1 ^ 2 + y1 ^ 2) * (y2 - y3) + (x2 ^ 2 + y2 ^ 2) * (y3 - y1) + (x3 ^ 2 + y3 ^ 2) * (y1 - y2)) / d1) yw = fn(((x1 ^ 2 + y1 ^ 2) * (x3 - x2) + (x2 ^ 2 + y2 ^ 2) * (x1 - x3) + (x3 ^ 2 + y3 ^ 2) * (x2 - x1)) / d1) -- 计算垂心坐标 s1 = x1 * (x2 * (y1 - y2) + x3 * (y3 - y1)) + (y2 - y3) * (x2 * x3 + (y1 - y2) * (y1 - y3)) s2 = x1 ^ 2 * (x2 - x3) + x1 * (x3 ^ 2 - x2 ^ 2 + y1 * y2 - y1 * y3) + x2 ^ 2 * x3 - x2 * (x3 ^ 2 + y1 * y2 - y2 * y3) + x3 * y3 * (y1 - y2) xc = fn(s1 / -determinant) yc = fn(s2 / determinant) return "重心(" .. xg .. "," .. yg .. ")\n内心(" .. xn .. "," .. yn .. ")\n外心(" .. xw .. "," .. yw .. ")\n垂心(" .. xc .. "," .. yc .. ")" end calc_methods["sjxx"] = triangle_centers methods_desc["sjxx"] = "已知三角形三个顶点坐标,求其“心”的坐标" -- 计算排列数 local function permutation(n, r) -- 参数检查 if type(n) ~= "number" or type(r) ~= "number" then return "错误:参数必须为数字" end if n < 0 or r < 0 or n ~= math.floor(n) or r ~= math.floor(r) then return "错误:参数必须为非负整数" end if r > n then return "错误:第二个参数不能大于第一个参数" end -- 特殊情况处理 if r == 0 then return 1 end if r == 1 then return n end -- 创建分子和分母的因数数组 local numerator_factors = {} local denominator_factors = {} -- 填充分子因数 (1 到 n) for i = 1, n do table.insert(numerator_factors, i) end -- 填充分母因数 (1 到 n-r) for i = 1, n-r do table.insert(denominator_factors, i) end -- 约分过程 for i = 1, #denominator_factors do local d = denominator_factors[i] for j = 1, #numerator_factors do local n = numerator_factors[j] local gcd_value = gcd(n, d) if gcd_value > 1 then numerator_factors[j] = n / gcd_value denominator_factors[i] = d / gcd_value d = denominator_factors[i] -- 更新d值 end end end -- 计算最终结果(此时分母应全部为1) local result = 1 for _, v in ipairs(numerator_factors) do result = result * v end return result end calc_methods["pls"] = permutation methods_desc["pls"] = "计算排列数" -- 计算组合数 local function combination(n, r) -- 参数检查 if type(n) ~= "number" or type(r) ~= "number" then return "错误:参数必须为数字" end if n < 0 or r < 0 or n ~= math.floor(n) or r ~= math.floor(r) then return "错误:参数必须为非负整数" end if r > n then return "错误:第二个参数不能大于第一个参数" end -- 使用组合数性质 C(n,r) = C(n,n-r) 减少计算量 r = math.min(r, n - r) if r == 0 or r == n then return 1 end if r == 1 or r == n-1 then return n end -- 创建分子和分母的因数数组 local numerator_factors = {} local denominator_factors = {} -- 填充分子因数 (n-r+1 到 n) for i = n - r + 1, n do table.insert(numerator_factors, i) end -- 填充分母因数 (1 到 r) for i = 1, r do table.insert(denominator_factors, i) end -- 约分过程 for i = 1, #denominator_factors do local d = denominator_factors[i] for j = 1, #numerator_factors do local n = numerator_factors[j] local gcd_value = gcd(n, d) if gcd_value > 1 then numerator_factors[j] = n / gcd_value denominator_factors[i] = d / gcd_value d = denominator_factors[i] -- 更新d值 end end end -- 计算最终结果(此时分母应全部为1) local result = 1 for _, v in ipairs(numerator_factors) do result = result * v end return result end calc_methods["zhs"] = combination methods_desc["zhs"] = "计算组合数" -- 已知直线l₁:A₁x+B₁y+C₁=0和l₂:A₂x+B₂y+C₂=0,求两条直线以彼此为轴的对称直线方程 local function symmetry_line(A1, B1, C1, A2, B2, C2) -- 检查参数正确性 if type(A1) ~= "number" or type(B1) ~= "number" or type(C1) ~= "number" or type(A2) ~= "number" or type(B2) ~= "number" or type(C2) ~= "number" then return "错误:参数必须是数字" end if (A1 == 0 and B1 == 0) or (A2 == 0 and B2 == 0) then return "错误:直线方程的系数不能同时为零" end -- 计算对称直线方程的系数 local a1, a2, b, A3, B3, C3, A4, B4, C4, ge1, ge2 a1 = A2 ^ 2 + B2 ^ 2 b = 2 * (A1 * A2 + B1 * B2) A3 = a1 * A1 - b * A2 B3 = a1 * B1 - b * B2 C3 = a1 * C1 - b * C2 a2 = A1 ^ 2 + B1 ^ 2 A4 = a2 * A2 - b * A1 B4 = a2 * B2 - b * B1 C4 = a2 * C2 - b * C1 ge1 = LineGeneralEquation(A3, B3, C3) ge2 = LineGeneralEquation(A4, B4, C4) return "直线l₁关于l₂的对称直线l₃的方程为:" .. ge1 .. "\n直线l₂关于l₁的对称直线l₄的方程为:" .. ge2 end calc_methods["lzx2"] = symmetry_line methods_desc["lzx2"] = "已知直线l₁:A₁x+B₁y+C₁=0和l₂:A₂x+B₂y+C₂=0,求两条直线以彼此为轴的对称直线方程" -- 已知一点P(x₁,y₁)和直线l:Ax+By+C=0,求直线l关于点P的对称直线l'的方程 local function dyzx2(x1, y1, A, B, C) -- 检查参数正确性 if type(x1) ~= "number" or type(y1) ~= "number" or type(A) ~= "number" or type(B) ~= "number" or type(C) ~= "number" then return "错误:参数必须是数字" end if A == 0 and B == 0 then return "直线方程的系数不能同时为零" end local A1, B1, C1, ge -- 计算对称直线方程的系数 A1 = A B1 = B C1 = -(2 * A * x1 + 2 * B * y1 + C) ge = LineGeneralEquation(A1, B1, C1) return "直线l关于点P的对称直线l'的方程为:" .. ge end calc_methods["dyzx2"] = dyzx2 methods_desc["dyzx2"] = "已知一点P(x₁,y₁)和直线l:Ax+By+C=0,求直线l关于点P的对称直线l'的方程" -- 已知两圆标准方程(x-x₁)²+(y-y₁)²=r₁²和(x-x₂)²+(y-y₂)²=r₂²,判断它们的位置关系 local function tcr1(x1, y1, r1, x2, y2, r2) -- 参数正确性检查 if type(x1) ~= "number" or type(y1) ~= "number" or type(r1) ~= "number" or type(x2) ~= "number" or type(y2) ~= "number" or type(r2) ~= "number" then return "错误:参数必须是数字" end if r1 <= 0 or r2 <= 0 then return "错误:半径必须为正数" end -- 特殊情况:两圆重合 if x1 == x2 and y1 == y2 and r1 == r2 then return "两圆重合" end local d, a, h, m, n, xj1, xj2, yj1, yj2, dj, e -- 计算两圆圆心距 d = fn(math.sqrt((x1 - x2) ^ 2 + (y1 - y2) ^ 2)) -- 判断位置关系 -- 两圆相离 if d > (r1 + r2) then return "两圆外离,圆心距为" .. d .. ",无交点" elseif d < math.abs(r1 - r2) then return "两圆内含,圆心距为" .. d .. ",无交点" end -- 两圆相交或相切,先计算相关参数 a = (r1 ^ 2 - r2 ^ 2 + d ^ 2) / (2 * d) h = math.sqrt(r1 ^ 2 - a ^ 2) m = (x2 - x1) / d n = (y2 - y1) / d -- 计算交点坐标 xj1 = fn(x1 + a * m + h * n) yj1 = fn(y1 + a * n - h * m) xj2 = fn(x1 + a * m - h * n) yj2 = fn(y1 + a * n + h * m) e = 1e-8 -- 精度控制,防止浮点数误差导致结果不准确 if math.abs(xj1) < e then xj1 = 0 end if math.abs(yj1) < e then yj1 = 0 end if math.abs(xj2) < e then xj2 = 0 end if math.abs(yj2) < e then yj2 = 0 end -- 计算相交弦弦长 dj = fn(math.sqrt((xj2 - xj1) ^ 2 + (yj2 - yj1) ^ 2)) -- 判断相切或相交,并给出交点坐标、圆心距和相交弦长 if d == (r1 + r2) then return "两圆外切,圆心距为" .. d .. "\n交点坐标为(" .. xj1 .. "," .. yj1 .. ")" elseif d == math.abs(r1 - r2) then return "两圆内切,圆心距为" .. d .. "\n交点坐标为(" .. xj1 .. "," .. yj1 .. ")" elseif math.abs(r1 - r2) < d and d < (r1 + r2) then return "两圆相交,圆心距为" .. d .. "\n交点坐标为(" .. xj1 .. "," .. yj1 .. ")和(" .. xj2 .. "," .. yj2 .. ")\n相交弦弦长为" .. dj end end calc_methods["tcr1"] = tcr1 methods_desc["tcr1"] = "已知两圆标准方程(x-x₁)²+(y-y₁)²=r₁²和(x-x₂)²+(y-y₂)²=r₂²,判断它们的位置关系" -- 已知两圆一般方程x²+y²+D₁x+E₁y+F₁=0和x²+y²+D₂x+E₂y+F₂=0,判断它们的位置关系 local function tcr2(D1, E1, F1, D2, E2, F2) -- 参数正确性检查 if type(D1) ~= "number" or type(E1) ~= "number" or type(F1) ~= "number" or type(D2) ~= "number" or type(E2) ~= "number" or type(F2) ~= "number" then return "错误:参数必须是数字" end local x1, y1, x2, y2, r1, r2 -- 计算两圆圆心,半径,圆心距 x1 = -D1 / 2 y1 = -E1 / 2 x2 = -D2 / 2 y2 = -E2 / 2 r1 = math.sqrt(x1 ^ 2 + y1 ^ 2 - F1) r2 = math.sqrt(x2 ^ 2 + y2 ^ 2 - F2) -- 调用函数输出结果 return tcr1(x1, y1, r1, x2, y2, r2) end calc_methods["tcr2"] = tcr2 methods_desc["tcr2"] = "已知两圆一般方程x²+y²+D₁x+E₁y+F₁=0和x²+y²+D₂x+E₂y+F₂=0,判断它们的位置关系" -- 求解勾股数 local function ggs(...) local args = { ... } local n = #args if n == 0 then return "请输入至少一个数" elseif n > 2 then return "最多只能输入2个数" end local function generateTriplets(a_param) local results = {} -- 生成作为直角边的解 if a_param % 2 == 1 then local c = (a_param ^ 2 - 1) / 2 local d = (a_param ^ 2 + 1) / 2 local triplet = { a_param, c, d } table.sort(triplet) table.insert(results, triplet) else local c = (a_param ^ 2) / 4 - 1 local d = (a_param ^ 2) / 4 + 1 local triplet = { a_param, c, d } table.sort(triplet) table.insert(results, triplet) end return results end local function findHypotenuseTriplets(m) local results = {} local m_squared = m * m local max_a = math.floor(m / math.sqrt(2)) for a = 1, max_a do local b_squared = m_squared - a * a if b_squared < 0 then break end local b = math.sqrt(b_squared) if b == math.floor(b) and b > a then local triplet = { a, b, m } table.sort(triplet) table.insert(results, triplet) end end return results end local function ggs1(a) if type(a) ~= "number" or a < 1 or a ~= math.floor(a) then return "参数必须是正整数" end if a % 2 == 1 and a < 3 then return "输入1个参数时,奇数须大于等于3" elseif a % 2 == 0 and a < 4 then return "输入1个参数时,偶数须大于等于4" end local results = {} -- 生成直角边解 local legTriplets = generateTriplets(a) for _, t in ipairs(legTriplets) do table.insert(results, t) end -- 生成斜边解 local hypoTrplets = findHypotenuseTriplets(a) for _, t in ipairs(hypoTrplets) do table.insert(results, t) end -- 去重 local seen = {} local unique = {} for _, t in ipairs(results) do local key = table.concat(t, ',') if not seen[key] then seen[key] = true table.insert(unique, t) end end if #unique == 0 then return "无解" else local parts = {} for _, t in ipairs(unique) do table.insert(parts, string.format("(%d,%d,%d)", t[1], t[2], t[3])) end return "勾股数为: " .. table.concat(parts, " 和 ") end end local function ggs2(a, b) if type(a) ~= "number" or a < 1 or a ~= math.floor(a) or type(b) ~= "number" or b < 1 or b ~= math.floor(b) then return "参数必须是正整数" end if a == b then return "两个参数不能相等" end local results = {} -- 两数作为直角边求斜边 local sum_sq = a ^ 2 + b ^ 2 local c = math.sqrt(sum_sq) if c == math.floor(c) then local triplet = { a, b, c } table.sort(triplet) table.insert(results, triplet) end -- 小数作为直角边,大数作为斜边求另一直角边 local sq = math.abs(a ^ 2 - b ^ 2) local d = math.sqrt(sq) if d == math.floor(d) then local triplet = { a, b, d } table.sort(triplet) table.insert(results, triplet) end -- 作为生成元求三元组 local part1 = math.abs(a ^ 2 - b ^ 2) local part2 = 2 * a * b local hypo = a ^ 2 + b ^ 2 local triplet = { part1, part2, hypo } table.sort(triplet) table.insert(results, triplet) -- 去重逻辑 local seen = {} local unique = {} for _, t in ipairs(results) do local key = table.concat(t, ",") if not seen[key] then seen[key] = true table.insert(unique, t) end end if #unique == 0 then return "无解" else local parts = {} for _, t in ipairs(unique) do table.insert(parts, string.format("(%d,%d,%d)", t[1], t[2], t[3])) end return "勾股数为: " .. table.concat(parts, " 和 ") end end return (n == 1) and ggs1(args[1]) or ggs2(args[1], args[2]) end calc_methods["ggs"] = ggs methods_desc["ggs"] = "求解勾股数" -- 批量随机数生成器 -- 参数模式1(3个参数):digits(位数)、count(数量)、unique(是否唯一,0为true/1为false) -- 参数模式2(4个参数):min(最小值)、max(最大值)、count(数量)、unique(是否唯一) local function generateRandomNumbers(...) local args = { ... } local min, max, count, unique -- 验证参数数量 if #args ~= 3 and #args ~= 4 then return "参数数量必须为3或4" end -- 解析参数模式 if #args == 3 then local digits, count_arg, unique_arg = args[1], args[2], args[3] -- 验证参数类型和范围 if type(digits) ~= "number" or type(count_arg) ~= "number" or type(unique_arg) ~= "number" then return "位数、数量和唯一性参数必须为数字" elseif digits < 1 or digits ~= math.floor(digits) then return "位数必须为正整数" elseif digits > 18 then return "位数不能超过18位" end min = 10 ^ (digits - 1) max = 10 ^ digits - 1 if digits == 1 then min = 1 end -- 一位数的特殊情况 count = count_arg unique = unique_arg else min, max, count, unique = args[1], args[2], args[3], args[4] -- 验证参数合法性 if type(min) ~= "number" or type(max) ~= "number" or type(count) ~= "number" then return "最小值、最大值和数量必须为数字" elseif min ~= math.floor(min) or max ~= math.floor(max) then return "最小值、最大值必须为整数" end end -- 通用参数验证 if min > max then min, max = max, min -- 自动交换顺序 end if count < 1 or count ~= math.floor(count) then return "数量必须为正整数" elseif unique ~= 0 and unique ~= 1 then return "控制唯一性的参数必须为0或1" elseif unique == 0 and count > (max - min + 1) then return "唯一性要求下,数量不能超过范围大小" end -- 存储随机数的表 local result = {} -- 生成随机数 if unique == 0 then local used = {} -- 记录已生成的随机数 for i = 1, count do local num repeat num = math.random(min, max) until not used[num] used[num] = true result[i] = num end else -- 非唯一情况,直接填充结果表 for i = 1, count do result[i] = math.random(min, max) end end -- 格式化输出 local formatted = {} for i = 1, #result do if i > 1 and (i - 1) % 10 == 0 then table.insert(formatted, "\n") end table.insert(formatted, tostring(result[i])) if i < #result and i % 10 ~= 0 then table.insert(formatted, ",") end end return table.concat(formatted) end calc_methods["psjs"] = generateRandomNumbers methods_desc["psjs"] = "批量随机数" -- 质因数分解(带优化输出格式) local function prime_factorization(n) -- 参数检查与位数限制 if type(n) ~= "number" or n <= 0 or math.floor(n) ~= n then return "参数必须是正整数" end local digits = #tostring(n) if digits > 18 then return "数字超限! 最大支持18位数字的质因数分解。" end -- 处理特殊情况 if n == 1 then return "1" end local factors = {} -- 处理2的因子 while n % 2 == 0 do factors[2] = (factors[2] or 0) + 1 n = math.floor(n / 2) end -- 处理奇数因子 local divisor = 3 local max_divisor = math.floor(math.sqrt(n)) while divisor <= max_divisor and n > 1 do while n % divisor == 0 do factors[divisor] = (factors[divisor] or 0) + 1 n = math.floor(n / divisor) max_divisor = math.floor(math.sqrt(n)) end divisor = divisor + 2 end -- 如果n仍然大于1,则n本身是一个质数 if n > 1 then factors[n] = (factors[n] or 0) + 1 end -- 优化的指数符号表(仅包含0-9) local superscript_digits = { ["0"] = "⁰", ["1"] = "¹", ["2"] = "²", ["3"] = "³", ["4"] = "⁴", ["5"] = "⁵", ["6"] = "⁶", ["7"] = "⁷", ["8"] = "⁸", ["9"] = "⁹" } -- 转换数字为上标形式(支持任意位数) local function to_superscript(num) local s = tostring(num) local result = "" for i = 1, #s do local c = s:sub(i, i) result = result .. (superscript_digits[c] or c) end return result end -- 生成输出字符串 local output = {} for factor, count in pairs(factors) do local str = tostring(factor) if count > 1 then str = str .. to_superscript(count) end table.insert(output, str) end -- 按质因数从小到大排序 table.sort(output, function(a, b) local fa = tonumber(a:match("^%d+")) local fb = tonumber(b:match("^%d+")) return fa < fb end) return table.concat(output, "×") end calc_methods["zys"] = prime_factorization methods_desc["zys"] = "质因数分解" -- 找质数(欧拉筛法) local function sieve_of_eratosthenes(n) if type(n) ~= "number" or n <= 1 or math.floor(n) ~= n then return "参数必须是大于1的正整数" end if n > 26338 then return "数字超限!" end local is_prime = {} local primes = {} -- 初始化数组,默认所有数都是质数 for i = 2, n do is_prime[i] = true end -- 欧拉筛法核心逻辑 for i = 2, n do if is_prime[i] then table.insert(primes, i) end -- 遍历已找到的质数,标记合数 for j = 1, #primes do local p = primes[j] local composite = i * p if composite > n then break end is_prime[composite] = false -- 关键优化:确保每个合数只被其最小质因数标记一次 if i % p == 0 then break end end end -- 格式化输出 local output = {} for i = 1, #primes do table.insert(output, tostring(primes[i])) if (i % 10 == 0) or (i == #primes) then table.insert(output, "\n") else table.insert(output, ",") end end -- 如果最后一个元素是换行符,则移除它 if #output > 0 and output[#output] == "\n" then output[#output] = nil end return table.concat(output) end calc_methods["zzs"] = sieve_of_eratosthenes methods_desc["zzs"] = "找质数" -- 24点计算器(含去重逻辑) local function solve24(...) -- 检查表中是否包含某个值 local function table_contains(tab, val) for _, value in ipairs(tab) do if value == val then return true end end return false end -- 生成随机数的函数 local function generate_numbers() math.randomseed(os.time()) local numbers = {} local magic_numbers = {} -- 新增:魔术字数组 for i = 1, 4 do numbers[i] = math.random(1, 13) -- 生成魔术字,1的魔术字固定为1 if numbers[i] == 1 then magic_numbers[i] = 1 else local newrd = math.random(1, 40) -- 确保魔术字不重复 while table_contains(magic_numbers, newrd) do newrd = math.random(1, 40) end magic_numbers[i] = newrd end end -- 如果数字有重复,魔术字也做同样的重复 for i = 1, 4 do for j = i + 1, 4 do if numbers[i] == numbers[j] then magic_numbers[j] = magic_numbers[i] end end end return numbers, magic_numbers end -- 去重用的魔术字解决方案记录 local hash_solutions = {} local solutions = {} -- 判断两个数是否接近(处理浮点数精度问题) local function is_close(a, b) return math.abs(a - b) < 1e-9 end -- 基本计算函数 local function compute(a, b, op) if op == '+' then return a + b elseif op == '-' then return a - b elseif op == '*' then return a * b elseif op == '/' then if b == 0 then return nil end return a / b end end -- 计算魔术字 local function compute_magic(a, b, op, magic_a, magic_b) if op == '+' then return magic_a + magic_b elseif op == '-' then return magic_a - magic_b elseif op == '*' then return magic_a * magic_b elseif op == '/' then if magic_b == 0 then return 999999999 end -- 避免除以0 return magic_a / magic_b end end -- 排列组合函数 local function permute(t) local result = {} local function permute_helper(current, remaining) if #remaining == 0 then table.insert(result, { table.unpack(current) }) else for i = 1, #remaining do local new_current = { table.unpack(current) } table.insert(new_current, remaining[i]) local new_remaining = {} for j = 1, #remaining do if j ~= i then table.insert(new_remaining, remaining[j]) end end permute_helper(new_current, new_remaining) end end end permute_helper({}, t) return result end -- 用于添加解决方案并去重 local function add_solution(expr, value, magic_value) if is_close(value, 24) then -- 检查魔术字是否已存在 local is_duplicate = false local replace_index = -1 for i, hash in ipairs(hash_solutions) do if math.abs(magic_value - hash) / (math.abs(magic_value) + 1e-9) < 1e-3 then is_duplicate = true replace_index = i break end end if not is_duplicate then -- 新解决方案,添加到列表 table.insert(solutions, expr) table.insert(hash_solutions, magic_value) else -- 检查是否需要替换为更优的解决方案 local need_replace = false local existing_expr = solutions[replace_index] -- 比较括号数量 local current_brackets = expr:gsub("[^%(%)]", ""):len() local existing_brackets = existing_expr:gsub("[^%(%)]", ""):len() if current_brackets < existing_brackets then need_replace = true -- 括号数量相同,比较减号数量 elseif current_brackets == existing_brackets then local current_minus = expr:gsub("[^-]", ""):len() local existing_minus = existing_expr:gsub("[^-]", ""):len() if current_minus < existing_minus then need_replace = true -- 减号数量相同,比较除号数量 elseif current_minus == existing_minus then local current_div = expr:gsub("[^/÷]", ""):len() local existing_div = existing_expr:gsub("[^/÷]", ""):len() if current_div < existing_div then need_replace = true -- 除号数量相同,比较表达式字典序 elseif current_div == existing_div and expr < existing_expr then need_replace = true end end end if need_replace then solutions[replace_index] = expr hash_solutions[replace_index] = magic_value end end end end -- 核心解决24点问题的函数 local function solve_24_with_magic(numbers, magic_numbers) local operators = { '+', '-', '*', '/' } local perms = permute(numbers) local magic_perms = permute(magic_numbers) -- 魔术字的排列组合 -- 遍历所有数字和魔术字的排列组合 for i, nums in ipairs(perms) do local magics = magic_perms[i] if magics then for _, op1 in ipairs(operators) do for _, op2 in ipairs(operators) do for _, op3 in ipairs(operators) do -- 情况1: ((a op1 b) op2 c) op3 d local v1 = compute(nums[1], nums[2], op1) local m1 = compute_magic(nums[1], nums[2], op1, magics[1], magics[2]) if v1 and m1 then local v2 = compute(v1, nums[3], op2) local m2 = compute_magic(v1, nums[3], op2, m1, magics[3]) if v2 and m2 then local v3 = compute(v2, nums[4], op3) local m3 = compute_magic(v2, nums[4], op3, m2, magics[4]) if v3 and m3 then local expr = string.format("((%d%s%d)%s%d)%s%d", nums[1], op1, nums[2], op2, nums[3], op3, nums[4]) add_solution(expr, v3, m3) end end end -- 情况2: (a op1 (b op2 c)) op3 d local v1 = compute(nums[2], nums[3], op2) local m1 = compute_magic(nums[2], nums[3], op2, magics[2], magics[3]) if v1 and m1 then local v2 = compute(nums[1], v1, op1) local m2 = compute_magic(nums[1], v1, op1, magics[1], m1) if v2 and m2 then local v3 = compute(v2, nums[4], op3) local m3 = compute_magic(v2, nums[4], op3, m2, magics[4]) if v3 and m3 then local expr = string.format("(%d%s(%d%s%d))%s%d", nums[1], op1, nums[2], op2, nums[3], op3, nums[4]) add_solution(expr, v3, m3) end end end -- 情况3: a op1 ((b op2 c) op3 d) local v1 = compute(nums[2], nums[3], op2) local m1 = compute_magic(nums[2], nums[3], op2, magics[2], magics[3]) if v1 and m1 then local v2 = compute(v1, nums[4], op3) local m2 = compute_magic(v1, nums[4], op3, m1, magics[4]) if v2 and m2 then local v3 = compute(nums[1], v2, op1) local m3 = compute_magic(nums[1], v2, op1, magics[1], m2) if v3 and m3 then local expr = string.format("%d%s((%d%s%d)%s%d)", nums[1], op1, nums[2], op2, nums[3], op3, nums[4]) add_solution(expr, v3, m3) end end end -- 情况4: a op1 (b op2 (c op3 d)) local v1 = compute(nums[3], nums[4], op3) local m1 = compute_magic(nums[3], nums[4], op3, magics[3], magics[4]) if v1 and m1 then local v2 = compute(nums[2], v1, op2) local m2 = compute_magic(nums[2], v1, op2, magics[2], m1) if v2 and m2 then local v3 = compute(nums[1], v2, op1) local m3 = compute_magic(nums[1], v2, op1, magics[1], m2) if v3 and m3 then local expr = string.format("%d%s(%d%s(%d%s%d))", nums[1], op1, nums[2], op2, nums[3], op3, nums[4]) add_solution(expr, v3, m3) end end end -- 情况5: (a op1 b) op2 (c op3 d) local v1 = compute(nums[1], nums[2], op1) local m1 = compute_magic(nums[1], nums[2], op1, magics[1], magics[2]) local v2 = compute(nums[3], nums[4], op3) local m2 = compute_magic(nums[3], nums[4], op3, magics[3], magics[4]) if v1 and m1 and v2 and m2 then local v3 = compute(v1, v2, op2) local m3 = compute_magic(v1, v2, op2, m1, m2) if v3 and m3 then local expr = string.format("(%d%s%d)%s(%d%s%d)", nums[1], op1, nums[2], op2, nums[3], op3, nums[4]) add_solution(expr, v3, m3) end end end end end end end return solutions end -- 处理函数参数 local arg = { ... } if #arg == 0 then -- 无参数,生成随机数 local numbers, magic_numbers = generate_numbers() return "生成的随机数: " .. table.concat(numbers, ", ") elseif #arg == 4 then -- 检查输入的四个参数是否都在1到13之间且为整数 for i, num in ipairs(arg) do if type(num) ~= "number" or num < 1 or num > 13 or num ~= math.floor(num) then return "错误:请输入4个1到13之间的整数。" end end -- 为输入的数字生成魔术字 local magic_numbers = {} for i, num in ipairs(arg) do if num == 1 then magic_numbers[i] = 1 else local newrd = math.random(1, 40) while table_contains(magic_numbers, newrd) do newrd = math.random(1, 40) end magic_numbers[i] = newrd end end -- 处理数字重复的情况 for i = 1, 4 do for j = i + 1, 4 do if arg[i] == arg[j] then magic_numbers[j] = magic_numbers[i] end end end -- 求解24点 local solutions = solve_24_with_magic(arg, magic_numbers) if #solutions == 0 then return "没有找到解决方案。" else return "共找到" .. #solutions .. "种解决方案:\n" .. table.concat(solutions, "\n") end else return "错误:请输入4个数字或者不输入参数以生成随机数。" end end calc_methods["tfp"] = solve24 methods_desc["tfp"] = "24点计算器" -- 单位换算脚本 -- 注意:单位是作为字符串类型参数传入的,所以输入时应加引号(单双均可,但不能混用) -- 否则会因参数类型错误而无法输出正确结果 local function dwhs(value, from_unit, to_unit) -- 单位转换系数表 local conversion_factors = { -- 长度 (相对于米) ai = 1e-10, -- 埃 nm = 1e-9, -- 纳米 wm = 1e-6, -- 微米 mm = 1e-3, -- 毫米 cm = 0.01, -- 厘米 dm = 0.1, -- 分米 m = 1, -- 米 km = 1e3, -- 千米 li = 500, -- 里 yc = 0.0254, -- 英寸 ft = 0.3048, -- 英尺 mile = 1609.344, -- 英里 nmi = 1852, -- 海里 zhang = 10 / 3, -- 丈 chi = 1 / 3, -- 尺 cun = 1 / 30, -- 寸 fen = 1 / 300, -- 分 -- 面积 (相对于平方米) mm2 = 1e-6, -- 平方毫米 cm2 = 1e-4, -- 平方厘米 dm2 = 1e-2, -- 平方分米 m2 = 1, -- 平方米 km2 = 1e6, -- 平方千米 pfyl = 2589988.1103, -- 平方英里 hm2 = 1e4, -- 公顷 sq = 2e5 / 3, -- 市顷 acre = 4046.8648, -- 英亩 sm = 2000 / 3, -- 市亩 gm = 100, -- 公亩 -- 体积 (相对于立方米) wl = 1e-9, -- 微升 mm3 = 1e-9, -- 立方毫米 ml = 1e-6, -- 毫升 cm3 = 1e-6, -- 立方厘米 cl = 1e-5, -- 厘升 dl = 1e-4, -- 分升 l = 1e-3, -- 升 dm3 = 1e-3, -- 立方分米 hl = 0.1, -- 公石 m3 = 1, -- 立方米 ygl = 4.5461e-3, -- 英制加仑 mgl = 3.78541e-3, -- 美制加仑 km3 = 1e9, -- 立方千米 -- 质量 (相对于克) wg = 1e-6, -- 微克 mg = 1e-3, -- 毫克 g = 1, -- 克 kg = 1e3, -- 千克 t = 1e6, -- 吨 lb = 453.59237, -- 磅 oz = 28.349523125, -- 盎司 ct = 0.2, -- 克拉 gd = 1e5, -- 公担 sd = 5e4, -- 市担 jin = 500, -- 斤 liang = 50, -- 两 qian = 5, -- 钱 dr = 1.771845195, -- 打兰 gr = 0.06479891, -- 格令 } -- 检查数值有效性 if type(value) ~= "number" or value <= 0 then return "错误: 第一个参数必须是有效的正数" end -- 检查单位有效性 if not conversion_factors[from_unit] then return "错误: 未知的原单位 '" .. tostring(from_unit) .. "'" end if not conversion_factors[to_unit] then return "错误: 未知的目标单位 '" .. tostring(to_unit) .. "'" end -- 将数字转换为上标字符 local function to_superscript(num) local superscripts = { "⁰", "¹", "²", "³", "⁴", "⁵", "⁶", "⁷", "⁸", "⁹" } local minus = "⁻" local str = tostring(num) local result = "" -- 处理负号 if str:sub(1, 1) == "-" then result = minus str = str:sub(2) end -- 移除前导零(除非是单独的0) str = str:gsub("^0+(%d)", "%1") if str == "" then str = "0" end -- 转换数字 for digit in str:gmatch("%d") do result = result .. superscripts[tonumber(digit) + 1] end return result end -- 格式化科学记数法输出为上标形式 local function format_scientific(num) local formatted = string.format("%.6e", num) local mantissa, exponent = string.match(formatted, "^(.-)e([%+%-]%d+)$") mantissa = mantissa:gsub("%.?0+$", ""):gsub("%.$", "") -- 移除指数前的+号 exponent = exponent:gsub("^%+", "") return mantissa .. "×10" .. to_superscript(exponent) end -- 判断是否应该使用科学计数法 local function should_use_scientific(num) local abs_num = math.abs(num) -- 对于大于等于1e5或小于等于1e-3的数字使用科学计数法 if abs_num >= 1e5 or (abs_num <= 1e-3 and abs_num > 0) then return true end -- 检查整数部分位数 local int_part = math.floor(abs_num) if int_part == 0 then -- 检查小数部分前导零的数量 local decimal_str = string.format("%.10f", abs_num - int_part) local leading_zeros = 0 for i = 3, #decimal_str do if decimal_str:sub(i, i) == "0" then leading_zeros = leading_zeros + 1 else break end end return leading_zeros >= 3 else return (math.log10(int_part) + 1) > 4 end end -- 格式化数字输出 local function format_number(num) if should_use_scientific(num) then return format_scientific(num) else return string.format("%.6f", num):gsub("%.?0+$", ""):gsub("%.$", "") end end -- 执行转换 local result = value * (conversion_factors[from_unit] / conversion_factors[to_unit]) -- 格式化输出 local formatted_result = format_number(result) -- 显示结果 return formatted_result end calc_methods["dwhs"] = dwhs methods_desc["dwhs"] = "单位换算,支持面积、质量、长度、体积" -- 数字进制转换 -- 注意:在输入有字母的非10进制数时,需加上引号(单双均可,但不能混用) -- 否则无法输出结果 local function convertBase(...) local args = { ... } local number, fromBase, toBase -- 参数数量处理 if #args == 3 then number, fromBase, toBase = args[1], args[2], args[3] elseif #args == 2 then number, toBase = args[1], args[2] fromBase = 10 -- 默认原进制为十进制 else return "参数数量必须为2或3" end -- 进制合法性检查 if type(fromBase) ~= "number" or type(toBase) ~= "number" then return "进制必须是数字类型" end if fromBase < 2 or fromBase > 36 or toBase < 2 or toBase > 36 then return "进制范围必须在2到36之间" end local number = tostring(number) -- 检查是否为有效数字格式 local sign = 1 local integerPart, fractionalPart -- 处理符号 if string.sub(number, 1, 1) == '-' then sign = -1 number = string.sub(number, 2) elseif string.sub(number, 1, 1) == '+' then number = string.sub(number, 2) end -- 分离整数和小数部分 local dotPos = string.find(number, '%.') if dotPos then integerPart = string.sub(number, 1, dotPos - 1) fractionalPart = string.sub(number, dotPos + 1) else integerPart = number fractionalPart = "" end -- 定义数字字符集 local digits = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ" -- 辅助函数:字符转数值 local function charToValue(c) return string.find(digits, string.upper(c), 1, true) - 1 end -- 辅助函数:数值转字符 local function valueToChar(v) return string.sub(digits, v + 1, v + 1) end -- 整数部分转换:原进制转十进制 local decimalInteger = 0 for i = 1, #integerPart do local c = string.sub(integerPart, i, i) local v = charToValue(c) if v == -1 or v >= fromBase then return "数字中包含无效字符或超出原进制范围" end decimalInteger = decimalInteger * fromBase + v end -- 小数部分转换:原进制转十进制 local decimalFraction = 0 local multiplier = 1 / fromBase for i = 1, #fractionalPart do local c = string.sub(fractionalPart, i, i) local v = charToValue(c) if v == -1 or v >= fromBase then return "数字中包含无效字符或超出原进制范围" end decimalFraction = decimalFraction + v * multiplier multiplier = multiplier / fromBase end -- 整数部分:十进制转目标进制 local targetInteger = {} local n = math.abs(decimalInteger) if n == 0 then targetInteger[1] = '0' else local i = 0 while n > 0 do i = i + 1 targetInteger[i] = valueToChar(n % toBase) n = math.floor(n / toBase) end -- 反转数组 for j = 1, math.floor(i / 2) do targetInteger[j], targetInteger[i - j + 1] = targetInteger[i - j + 1], targetInteger[j] end end -- 小数部分:十进制转目标进制(精度限制为10位) local targetFraction = {} local f = decimalFraction local maxFractionDigits = 10 if f > 0 then targetFraction[1] = '.' local i = 1 while f > 0 and i <= maxFractionDigits do f = f * toBase local intPart = math.floor(f) targetFraction[i + 1] = valueToChar(intPart) f = f - intPart i = i + 1 end end -- 组合结果 local result = {} if sign == -1 then result[#result + 1] = '-' end for i = 1, #targetInteger do result[#result + 1] = targetInteger[i] end for i = 1, #targetFraction do result[#result + 1] = targetFraction[i] end return table.concat(result) end calc_methods["jzzh"] = convertBase methods_desc["jzzh"] = "数字进制转换,支持2~36进制" -- 执行普通计算的辅助函数 local function execute_normal_calculation(input, seg, express, env) if (string.len(express) < 2) and (not calc_methods[express]) then return end if (string.len(express) == 2) and (express:match("^%d[^%!]$")) then return end local code = replaceToFactorial(express) local loaded_func, load_error = load("return " .. code, "calculate", "t", calc_methods) if loaded_func then local success, result = pcall(loaded_func) if success then local display_value if type(result) == "number" then display_value = format_number_for_display(result) else display_value = tostring(result) end yield(Candidate(input, seg.start, seg._end, display_value, "")) yield(Candidate(input, seg.start, seg._end, express .. "=" .. display_value, "")) else yield(Candidate(input, seg.start, seg._end, express, "执行错误")) end else yield(Candidate(input, seg.start, seg._end, express, "解析失败")) end end -- 执行函数调用的辅助函数 local function execute_function_call(input, seg, func_name, params, env) -- 检查函数是否存在 if not calc_methods[func_name] then yield(Candidate(input, seg.start, seg._end, "错误: 函数 " .. func_name .. " 不存在", "")) return end local func = calc_methods[func_name] -- 获取函数的参数数量 local function get_function_param_count(func) if type(func) ~= "function" then return nil -- 不是函数,返回nil end -- 获取函数的字符串表示,从中提取参数信息 local func_str = string.dump(func) if not func_str then return nil end -- 从函数的调试信息中获取参数数量(更可靠的方法) local info = debug.getinfo(func) if info and info.nparams then return info.nparams end return nil -- 无法确定参数数量 end -- 获取函数的参数数量 local expected_param_count = get_function_param_count(func) -- 如果有明确的参数数量要求,进行验证 if expected_param_count and expected_param_count > 0 then if #params ~= expected_param_count then yield(Candidate(input, seg.start, seg._end, "错误: 函数 " .. func_name .. " 需要 " .. expected_param_count .. " 个参数,但提供了 " .. #params .. " 个", "")) return end end local function smart_quote_params(param_list, fn_name) -- 判断哪些函数需要特殊处理其字符串参数 -- key: 函数名, value: 需要加引号的参数索引表 local string_param_funcs = { jzzh = {1}, -- jzzh函数的第1个参数(要转换的数字)可能需要引号 dwhs = {2, 3} -- dwhs函数的第2(原单位)和第3(目标单位)个参数需要引号 } local indices_to_quote = string_param_funcs[fn_name] if not indices_to_quote then -- 如果这个函数不需要特殊处理,直接返回原参数列表 return param_list end local processed_params = {} for i, param in ipairs(param_list) do local p = param -- 检查当前参数索引是否需要被引号包裹 for _, idx in ipairs(indices_to_quote) do if i == idx then -- 检查这个参数:如果它不是纯数字,也不是一个已经被引号括起来的字符串,则为其加上引号 if not p:match("^%d+$") and not p:match("^['\"].*['\"]$") then p = "'" .. p .. "'" end break -- 找到匹配的索引后就跳出内层循环 end end table.insert(processed_params, p) end return processed_params end local success, result -- 关键修改:正确处理无参数情况 if #params > 0 then -- 有参数的情况:构建函数调用字符串 -- 在处理参数之前,先进行智能引号处理 local processed_params = smart_quote_params(params, func_name) local param_str = table.concat(processed_params, ", ") local call_str = func_name .. "(" .. param_str .. ")" local loaded_func, load_error = load("return " .. call_str, "calculate", "t", calc_methods) if loaded_func then success, result = pcall(loaded_func) else success = false result = "函数调用语法错误: " .. tostring(load_error) end else -- 无参数情况:直接调用函数 if type(func) == "function" then success, result = pcall(func) else -- 如果不是函数,可能是其他类型的值 success = true result = func end end -- 显示结果 if success then -- 关键修改:正确处理函数返回值 if type(result) == "function" then -- 如果结果是函数,说明需要执行它 success, result = pcall(result) if not success then yield(Candidate(input, seg.start, seg._end, "错误: 函数执行失败: " .. tostring(result), "")) return end end local display_value if type(result) == "number" then display_value = format_number_for_display(result) else display_value = tostring(result) end -- 显示当前结果 yield(Candidate(input, seg.start, seg._end, display_value, "")) -- 显示完整调用 local param_display = #params > 0 and table.concat(params, ", ") or "" local call_display = func_name .. "(" .. param_display .. ")" yield(Candidate(input, seg.start, seg._end, call_display .. " = " .. display_value, "")) else -- 显示错误信息 yield(Candidate(input, seg.start, seg._end, "错误: " .. tostring(result), "")) end end function T.func(input, seg, env) local composition = env.engine.context.composition if composition:empty() then return end local segment = composition:back() if startsWith(input, T.prefix) or (seg:has_tag("calculator")) then segment.prompt = "〔" .. T.tips .. "〕" segment.tags = segment.tags + Set({ "calculator" }) -- 提取算式 local express = input:gsub(T.prefix, ""):gsub("^/vs", "") local code = replaceToFactorial(express) local loaded_func, load_error = load("return " .. code, "calculate", "t", calc_methods) if loaded_func and (type(methods_desc[code]) == "string") then yield(Candidate(input, seg.start, seg._end, express .. ":" .. methods_desc[code], "")) end -- 检查是否是单个全局变量(不包含运算符的纯标识符) if express:match("^[a-zA-Z][a-zA-Z0-9_]*$") then local identifier = express local value = calc_methods[identifier] -- 如果是已定义的数值常量,直接显示其值 if type(value) == "number" then local formatted_result = format_number_for_display(value) local description = methods_desc[identifier] or "" -- 创建候选词 local cand = Candidate("calculator", seg.start, seg._end, formatted_result, description) cand.preedit = input cand.quality = 100 yield(cand) -- 同时显示带变量名的完整表达式结果 local expr_cand = Candidate("calculator", seg.start, seg._end, identifier .. " = " .. formatted_result, description) expr_cand.preedit = input expr_cand.quality = 99 yield(expr_cand) return end -- 让全局变量可以参与运算 elseif express:match("^([a-zA-Z][a-zA-Z0-9_]*)") then local identifier = express:match("^([a-zA-Z][a-zA-Z0-9_]*)") if identifier then local value = calc_methods[identifier] -- 如果是已定义的数值常量,按普通计算处理 if type(value) == "number" then execute_normal_calculation(input, seg, express, env) return end end end -- 检查是否是函数调用(英文字母开头且不包含括号) if express:match("^[a-zA-Z]") and not express:find("[()]") then -- 尝试按免括号方式处理函数调用 local func_name = nil local param_part = "" -- 从长到短尝试匹配函数名 for i = #express, 1, -1 do local potential_name = express:sub(1, i) if calc_methods[potential_name] ~= nil then func_name = potential_name param_part = express:sub(i + 1) break end end if func_name then -- 如果找到函数名,提取参数部分 local params = {} if param_part and param_part ~= "" then local current_param = "" local in_quotes = false local quote_char = "" for i = 1, #param_part do local char = param_part:sub(i, i) if in_quotes then if char == quote_char then in_quotes = false table.insert(params, current_param) current_param = "" else current_param = current_param .. char end else if char == '"' or char == "'" then in_quotes = true quote_char = char if current_param ~= "" then table.insert(params, current_param) current_param = "" end elseif char == "," then if current_param ~= "" then table.insert(params, current_param) current_param = "" end else current_param = current_param .. char end end end if current_param ~= "" then table.insert(params, current_param) end end -- 清理参数 for i, param in ipairs(params) do params[i] = param:match("^%s*(.-)%s*$") end -- 执行函数 execute_function_call(input, seg, func_name, params, env) return end end -- 其他情况执行普通计算 execute_normal_calculation(input, seg, express, env) end end return T