【问题标题】:How to calculate big combinatorics amount in tsql如何在sql中计算大组合数
【发布时间】:2017-02-08 14:52:16
【问题描述】:

在 sql2014 中,我有一个包含 4 个整数(W、X、Y、Z)和一个 bigint B 的表。 B = C(X,Z)*C(WX;YZ) 其中 C(n,k) 代表取自 n 个对象的 k 个对象的组合,即通常的 n!/[k!(nk)!]

W、X、Y、Z的最大值是40,所以最大的B是1.37847E+11 我可以使用 Excel 计算正确的值(使用函数 COMBIN),但我不能在 SQL 中使用相同的值。我可以生成包含我需要的所有 W、X、Y、Z 组合的表格,但是当我尝试为大值计算 B 时,我不知道如何处理“40!”之类的东西。

我想使用预先插入阶乘值的 CTE,例如:

;WITH factorials AS(
SELECT 2 as N, 2 AS F
UNION ALL
SELECT 3,6
UNION ALL...
)

但我不知道如何存储 40!之类的。

使用.NET填表不是一种选择,应该由SQL来完成。

之前我什至想过使用像 CTE 这样的表并将阶乘存储在两三列中,第一列存储数十亿,第二列存储数十亿,依此类推(使用 INT),但后来我不知道如何在这样存储的数字之间进行除法,如 (Ax10^9+B)/(Cx10^9+D)。

如何在 tsql 中管理大于 bigint 的整数?

【问题讨论】:

  • 现在我正在考虑多项式之间的良好旧除法......这似乎几乎是微不足道的......但事实并非如此!因为我可能仍然需要处理太大的数字

标签: tsql combinations factorial bigint


【解决方案1】:

我确信这不是一个完整的解决方案,但也许它会给你一些关于如何开始的想法。也许您可以将其设为存储过程并传入@n 和@k

当我将它转换回 BIGINT 时,使用 DOUBLE 似乎不会导致任何问题。也许其他人可以评论这样做的明显危险。

DECLARE @final_value DOUBLE PRECISION
DECLARE @n INT = 40
DECLARE @k INT = 20

;WITH CTE AS 
(
SELECT 1 AS num,CAST(1 AS DOUBLE PRECISION) AS factorial
UNION ALL
SELECT num+1,CAST(factorial*(num+1)AS DOUBLE PRECISION) FROM CTE
WHERE CTE.num < 40
)

SELECT * INTO #temp_numbers FROM CTE 

SET @final_value = (SELECT factorial FROM #temp_numbers WHERE num = @n) /
    (SELECT factorial FROM #temp_numbers WHERE num = @k) / 
    (SELECT factorial FROM #temp_numbers WHERE num = (@n-@k))  

PRINT CAST(@final_value AS BIGINT)
DROP TABLE #temp_numbers

【讨论】:

  • 这正是我所需要的。我今天有机会将您的答案应用到我的案例中,并且效果非常好且非常快。谢谢!
【解决方案2】:

请在此处检查十进制和数字数据类型:https://technet.microsoft.com/en-us/library/ms187746.aspx

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-02-07
    • 2011-05-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多