@@ -115,6 +115,8 @@ static ID id_half;
115115 */
116116static unsigned short VpGetException (void );
117117static void VpSetException (unsigned short f );
118+ static void VpCheckException (Real * p , bool always );
119+ static VALUE VpCheckGetValue (Real * p );
118120static void VpInternalRound (Real * c , size_t ixDigit , DECDIG vPrev , DECDIG v );
119121static int VpLimitRound (Real * c , size_t ixDigit );
120122static Real * VpCopy (Real * pv , Real const * const x );
@@ -165,27 +167,6 @@ is_kind_of_BigDecimal(VALUE const v)
165167 return rb_typeddata_is_kind_of (v , & BigDecimal_data_type );
166168}
167169
168- static void
169- VpCheckException (Real * p , bool always )
170- {
171- if (VpIsNaN (p )) {
172- VpException (VP_EXCEPTION_NaN , "Computation results in 'NaN' (Not a Number)" , always );
173- }
174- else if (VpIsPosInf (p )) {
175- VpException (VP_EXCEPTION_INFINITY , "Computation results in 'Infinity'" , always );
176- }
177- else if (VpIsNegInf (p )) {
178- VpException (VP_EXCEPTION_INFINITY , "Computation results in '-Infinity'" , always );
179- }
180- }
181-
182- static VALUE
183- VpCheckGetValue (Real * p )
184- {
185- VpCheckException (p , false);
186- return p -> obj ;
187- }
188-
189170NORETURN (static void cannot_be_coerced_into_BigDecimal (VALUE , VALUE ));
190171
191172static void
@@ -1656,12 +1637,15 @@ BigDecimal_divide(VALUE self, VALUE r, Real **c, Real **res, Real **div)
16561637}
16571638
16581639/* call-seq:
1659- * a / b -> bigdecimal
1660- * quo(value) -> bigdecimal
1640+ * a / b -> bigdecimal
16611641 *
16621642 * Divide by the specified value.
16631643 *
1644+ * The result precision will be the precision of the larger operand,
1645+ * but its minimum is 2*Float::DIG.
1646+ *
16641647 * See BigDecimal#div.
1648+ * See BigDecimal#quo.
16651649 */
16661650static VALUE
16671651BigDecimal_div (VALUE self , VALUE r )
@@ -1683,6 +1667,45 @@ BigDecimal_div(VALUE self, VALUE r)
16831667 return VpCheckGetValue (c );
16841668}
16851669
1670+ static VALUE BigDecimal_round (int argc , VALUE * argv , VALUE self );
1671+
1672+ /* call-seq:
1673+ * quo(value) -> bigdecimal
1674+ * quo(value, digits) -> bigdecimal
1675+ *
1676+ * Divide by the specified value.
1677+ *
1678+ * digits:: If specified and less than the number of significant digits of
1679+ * the result, the result is rounded to the given number of digits,
1680+ * according to the rounding mode indicated by BigDecimal.mode.
1681+ *
1682+ * If digits is 0 or omitted, the result is the same as for the
1683+ * / operator.
1684+ *
1685+ * See BigDecimal#/.
1686+ * See BigDecimal#div.
1687+ */
1688+ static VALUE
1689+ BigDecimal_quo (int argc , VALUE * argv , VALUE self )
1690+ {
1691+ VALUE value , digits , result ;
1692+ SIGNED_VALUE n = -1 ;
1693+
1694+ argc = rb_scan_args (argc , argv , "11" , & value , & digits );
1695+ if (argc > 1 ) {
1696+ n = GetPrecisionInt (digits );
1697+ }
1698+
1699+ if (n > 0 ) {
1700+ result = BigDecimal_div2 (self , value , digits );
1701+ }
1702+ else {
1703+ result = BigDecimal_div (self , value );
1704+ }
1705+
1706+ return result ;
1707+ }
1708+
16861709/*
16871710 * %: mod = a%b = a - (a.to_f/b).floor * b
16881711 * div = (a.to_f/b).floor
@@ -1964,6 +1987,7 @@ BigDecimal_div2(VALUE self, VALUE b, VALUE n)
19641987 * Document-method: BigDecimal#div
19651988 *
19661989 * call-seq:
1990+ * div(value) -> integer
19671991 * div(value, digits) -> bigdecimal or integer
19681992 *
19691993 * Divide by the specified value.
@@ -1978,6 +2002,9 @@ BigDecimal_div2(VALUE self, VALUE b, VALUE n)
19782002 * If digits is not specified, the result is an integer,
19792003 * by analogy with Float#div; see also BigDecimal#divmod.
19802004 *
2005+ * See BigDecimal#/.
2006+ * See BigDecimal#quo.
2007+ *
19812008 * Examples:
19822009 *
19832010 * a = BigDecimal("4")
@@ -4272,7 +4299,7 @@ Init_bigdecimal(void)
42724299 rb_define_method (rb_cBigDecimal , "-@" , BigDecimal_neg , 0 );
42734300 rb_define_method (rb_cBigDecimal , "*" , BigDecimal_mult , 1 );
42744301 rb_define_method (rb_cBigDecimal , "/" , BigDecimal_div , 1 );
4275- rb_define_method (rb_cBigDecimal , "quo" , BigDecimal_div , 1 );
4302+ rb_define_method (rb_cBigDecimal , "quo" , BigDecimal_quo , - 1 );
42764303 rb_define_method (rb_cBigDecimal , "%" , BigDecimal_mod , 1 );
42774304 rb_define_method (rb_cBigDecimal , "modulo" , BigDecimal_mod , 1 );
42784305 rb_define_method (rb_cBigDecimal , "remainder" , BigDecimal_remainder , 1 );
@@ -4446,6 +4473,27 @@ VpSetException(unsigned short f)
44464473 bigdecimal_set_thread_local_exception_mode (f );
44474474}
44484475
4476+ static void
4477+ VpCheckException (Real * p , bool always )
4478+ {
4479+ if (VpIsNaN (p )) {
4480+ VpException (VP_EXCEPTION_NaN , "Computation results in 'NaN' (Not a Number)" , always );
4481+ }
4482+ else if (VpIsPosInf (p )) {
4483+ VpException (VP_EXCEPTION_INFINITY , "Computation results in 'Infinity'" , always );
4484+ }
4485+ else if (VpIsNegInf (p )) {
4486+ VpException (VP_EXCEPTION_INFINITY , "Computation results in '-Infinity'" , always );
4487+ }
4488+ }
4489+
4490+ static VALUE
4491+ VpCheckGetValue (Real * p )
4492+ {
4493+ VpCheckException (p , false);
4494+ return p -> obj ;
4495+ }
4496+
44494497/*
44504498 * Precision limit.
44514499 */
0 commit comments