@@ -680,7 +680,7 @@ public static RubyFloat erfc19(ThreadContext context, IRubyObject recv, IRubyObj
680680
681681 @ JRubyMethod (name = "gamma" , required = 1 , module = true , visibility = Visibility .PRIVATE )
682682 public static RubyFloat gamma (ThreadContext context , IRubyObject recv , IRubyObject x ) {
683- double value = (( RubyFloat ) RubyKernel .new_float (recv , x ) ).getDoubleValue ();
683+ double value = RubyKernel .new_float (recv , x ).getDoubleValue ();
684684 double result = nemes_gamma (value );
685685 /* note nemes_gamma can return Double.POSITIVE_INFINITY or Double.NEGATIVE_INFINITY
686686 * when value is an integer less than 1.
@@ -719,7 +719,7 @@ public static RubyFloat gamma(ThreadContext context, IRubyObject recv, IRubyObje
719719
720720 @ JRubyMethod (name = "lgamma" , required = 1 , module = true , visibility = Visibility .PRIVATE )
721721 public static RubyArray lgamma (ThreadContext context , IRubyObject recv , IRubyObject x ) {
722- double value = RubyKernel .new_float (recv , x ).getDoubleValue ();
722+ double value = RubyKernel .new_float (recv , x ).getDoubleValue ();
723723 // JRUBY-4653: Could this error checking done more elegantly?
724724 if (value < 0 && Double .isInfinite (value )) throw context .runtime .newMathDomainError ("lgamma" );
725725
@@ -743,22 +743,22 @@ public static double nemes_gamma(double x) {
743743 * Inner class to help with Γ functions
744744 */
745745 public static class NemesLogGamma {
746- public double value ;
747- public double sign = 1 ;
746+ public final double value ;
747+ public final double sign ;
748748
749749 public NemesLogGamma (double x ) {
750750 if (Double .isInfinite (x )) {
751- value = Double .POSITIVE_INFINITY ;
751+ value = Double .POSITIVE_INFINITY ; sign = 1 ;
752752 return ;
753753 }
754754
755755 if (Double .isNaN (x )) {
756- value = Double .NaN ;
756+ value = Double .NaN ; sign = 1 ;
757757 return ;
758758 }
759759
760760 double int_part = (int ) x ;
761- sign = ( int_part % 2 == 0 && ( x - int_part ) != 0.0 && ( x < 0 )) ? - 1 : 1 ;
761+ sign = signum ( x , int_part );
762762 if ((x - int_part ) == 0.0 && 0 < int_part && int_part <= FACTORIAL .length ) {
763763 value = Math .log (FACTORIAL [(int ) int_part - 1 ]);
764764 }
@@ -779,5 +779,14 @@ else if (x < 10) {
779779 (Math .log (2 ) + Math .log (Math .PI ) - Math .log (x )) / 2.0 ;
780780 }
781781 }
782+
783+ private static int signum (final double x , final double int_part ) {
784+ return ( (int_part % 2 == 0 && (x - int_part ) != 0.0 && (x < 0 )) || negZero (x ) ) ? -1 : 1 ;
785+ }
786+
787+ private static boolean negZero (final double x ) {
788+ return x == 0.0 && Double .doubleToRawLongBits (x ) != 0 ; // detect -0.0 (since in Java: `0.0 == -0.0`)
789+ }
790+
782791 }
783792}
0 commit comments