状况
我需要为我的数学课程制作关于组合和排列的程序。如果你想计算它们,你必须处理阶乘,我写了这个典型的递归函数:
//TCombinazioni is a class that I have created to solve Combinations
function TCombinazioni.fattoriale(const x: integer): Int64;
begin
Result:= 1;
if x > 0 then
begin
Result:= fattoriale(x-1)*x;
end;
end;
问题
我已在我的班级TCombinazioni
中编写此代码:
function TCombinazioni.getSoluzioni: Int64;
begin
//C(n,k) = (n+k-1)! / (k! * (n-1)!)
Result := fattoriale(n+k-1) div (fattoriale(k) * fattoriale(n-1));
end;
代码本身是正确的,如果n
和k
(两个整数)都很小,则函数返回所需的数字。输入大数字时会出现问题,因为因子很快就会增长。在这里你看到一个例子。
在左侧,您可以看到输出11440是正确的,但在右侧则不正确。我知道这种计算是危险的"因为我正在处理大整数,即使它们被声明为Int64
。
据我所知,类型Int64
是最大的整数类型,但如果我尝试用大整数进行计算,还有其他可能性吗?
可能的解决方案
很简单,我可以设置n和k不能大于10(例如我不喜欢这样做)
使用浮点运算。我在想我可以使用getSoluzioni
函数和Extended
返回值(而不是Int64)。由于这些操作的结果必须是一个整数,我可以检查double是否有一个等于零的小数部分。如果没有,我将不接受结果。
我正在考虑第2点,因为Extended比Int64具有更广泛的值。 Delphi中的扩展部门比Int64部门更精确吗?
我希望能够得到一个不错的结果,例如至少n = 14和k = 8。
答案 0 :(得分:7)
扩展具有64位精度,因此没有增益。另外,它使编码变得非常复杂。你可以通过重写它来进行分割,从而使计算不易出现溢出。这在一定程度上会有所帮助。因此,当你在分子和分母中找到相同的因子时,只需从两者中删除它。
但实际上你需要的是一个大整数库。在网上搜索一个。