@@ -869,10 +869,16 @@ public IRubyObject op_quo20(ThreadContext context, IRubyObject other) {
869869 }
870870
871871 private IRubyObject op_quo19_20 (ThreadContext context , IRubyObject other ) {
872- RubyObject preciseOther = getVpValue19 (context , other , true );
872+ RubyBigDecimal preciseOther = getVpValue19 (context , other , true );
873873 // regular division with some default precision
874- // TODO: proper algorithm to set the precision
875- return op_div (context , preciseOther , getRuntime ().newFixnum (200 ));
874+ // proper algorithm to set the precision
875+ // the precision is multiple of 4
876+ // and the precision is larger than len * 2
877+ int len = value .precision () + preciseOther .value .precision ();
878+ int pow = len / 4 ;
879+ int precision = (pow + 1 ) * 4 * 2 ;
880+
881+ return op_div (context , preciseOther , getRuntime ().newFixnum (precision ));
876882 }
877883
878884 public IRubyObject op_div (ThreadContext context , IRubyObject other ) {
@@ -923,10 +929,9 @@ public IRubyObject op_div(ThreadContext context, IRubyObject other, IRubyObject
923929 // MRI behavior: "If digits is 0, the result is the same as the / operator."
924930 if (scale == 0 ) return op_quo (context , other );
925931
926- // TODO: better algorithm to set precision needed
927- int prec = Math .max (200 , scale );
932+ MathContext mathContext = new MathContext (scale , getRoundingMode (context .runtime ));
928933 return new RubyBigDecimal (context .runtime ,
929- value .divide (val .value , new MathContext ( prec , RoundingMode . HALF_UP ) )).setResult (scale );
934+ value .divide (val .value , mathContext )).setResult (scale );
930935 }
931936
932937 @ JRubyMethod (name = "div" )
0 commit comments