@@ -737,6 +737,8 @@ def gamma(x, prec)
737737 return pi . div ( gamma ( 1 - x , prec2 ) . mult ( sin , prec2 ) , prec )
738738 elsif x . frac . zero? && x < 1000 * prec
739739 return _gamma_positive_integer ( x , prec2 ) . mult ( 1 , prec )
740+ elsif x < ( prec / prec . bit_length ) **2
741+ return _gamma_lagrange ( x , prec2 ) . mult ( 1 , prec )
740742 end
741743
742744 a , sum = _gamma_spouge_sum_part ( x , prec2 )
@@ -764,8 +766,9 @@ def gamma(x, prec)
764766 [ prd , coef ]
765767 end
766768
767- def gamma_lagrange ( x , prec )
769+ private_class_method def _gamma_lagrange ( x , prec )
768770 # Calculate approximage gamma by Lagrange interpolation of b**x/x! at x=b-l, b-l+1, ..., b+l
771+ # Estimated time compexity: O(prec**2), precondition: 0 < x < const * (prec / prec.bit_length)**2
769772
770773 x = BigDecimal ( x ) - 1
771774 l = prec
@@ -904,8 +907,13 @@ def lgamma(x, prec)
904907 end
905908
906909 prec2 += [ -diff1_exponent , -diff2_exponent , 0 ] . max
907- a , sum = _gamma_spouge_sum_part ( x , prec2 )
908- log_gamma = BigMath . log ( sum , prec2 ) . add ( ( x - 0.5 ) . mult ( BigMath . log ( x . add ( a - 1 , prec2 ) , prec2 ) , prec2 ) + 1 - x , prec )
910+
911+ if x < ( prec / prec . bit_length ) **2
912+ log_gamma = BigMath . log ( _gamma_lagrange ( x , prec2 ) , prec )
913+ else
914+ a , sum = _gamma_spouge_sum_part ( x , prec2 )
915+ log_gamma = BigMath . log ( sum , prec2 ) . add ( ( x - 0.5 ) . mult ( BigMath . log ( x . add ( a - 1 , prec2 ) , prec2 ) , prec2 ) + 1 - x , prec )
916+ end
909917 [ log_gamma , 1 ]
910918 end
911919 end
0 commit comments