@@ -591,37 +591,22 @@ Params:
591591Returns: n choose k
592592Complexity: O(min(k, n - k))
593593+/
594- template binomialCoefficient (DivisionType = void )
595- if (is (DivisionType == void ) || __traits(isFloating, DivisionType))
594+ auto binomialCoefficient
595+ (size_t coefficientSize = 128 , Exp = sizediff_t )
596+ (ulong n, uint k)
597+ if (coefficientSize % (size_t .sizeof * 8 ) == 0 && coefficientSize >= (size_t .sizeof * 8 ))
598+ in (k <= n)
596599{
597- auto binomialCoefficient
598- (size_t coefficientSize = 128 , Exp = sizediff_t )
599- (ulong n, uint k)
600- if (coefficientSize % (size_t .sizeof * 8 ) == 0 && coefficientSize >= (size_t .sizeof * 8 ))
601- in (k <= n)
602- {
603- import mir.bignum.fp: Fp;
604-
605- alias R = Fp! (coefficientSize, Exp);
600+ import mir.bignum.fp: Fp;
606601
607- // TODO: For DivisionType == void
608- // use full precision division for void when Fp division is ready
609- static if (is (DivisionType == void ))
610- alias T = real ;
611- else
612- alias T = DivisionType;
613-
614- if (k > n - k)
615- k = cast (uint )(n - k);
616-
617- auto a = factorial! (coefficientSize, Exp)(k, n - k + 1 );
618- auto b = factorial! (coefficientSize, Exp)(k);
619- auto exponent = a.exponent - b.exponent;
620- a.exponent = b.exponent = - coefficientSize;
621- auto ret = R(cast (T) a / cast (T) b);
622- ret.exponent += exponent;
623- return ret;
624- }
602+ alias R = Fp! (coefficientSize, Exp);
603+
604+ if (k > n - k)
605+ k = cast (uint )(n - k);
606+
607+ auto a = factorial! (coefficientSize, Exp)(k, n - k + 1 );
608+ auto b = factorial! (coefficientSize, Exp)(k);
609+ return a / b;
625610}
626611
627612// /
@@ -632,7 +617,7 @@ unittest
632617 import mir.bignum.fp: Fp;
633618 import mir.math.common: approxEqual;
634619
635- static assert (is (typeof (binomialCoefficient! double (30 , 18 )) == Fp! 128 ), typeof (binomialCoefficient! double (30 , 18 )).stringof);
620+ static assert (is (typeof (binomialCoefficient(30 , 18 )) == Fp! 128 ), typeof (binomialCoefficient(30 , 18 )).stringof);
636621 static assert (cast (double ) binomialCoefficient(30 , 18 ) == 86493225 );
637622
638623 assert (approxEqual(cast (double ) binomialCoefficient(100 , 40 ), 1.374623414580281150126736972e+28 ));
0 commit comments