@@ -196,19 +196,6 @@ rbd_allocate_struct_zero(int sign, size_t const digits)
196
196
return real ;
197
197
}
198
198
199
- // Only used in VpSqrt through BigDecimal_sqrt
200
- MAYBE_UNUSED (static inline Real * rbd_allocate_struct_one_nolimit (int sign , size_t const digits ));
201
- #define NewOneNolimit rbd_allocate_struct_one_nolimit
202
- static inline Real *
203
- rbd_allocate_struct_one_nolimit (int sign , size_t const digits )
204
- {
205
- Real * real = rbd_allocate_struct_decimal_digits (digits );
206
- VpSetOne (real );
207
- if (sign < 0 )
208
- VpSetSign (real , VP_SIGN_NEGATIVE_FINITE );
209
- return real ;
210
- }
211
-
212
199
/*
213
200
* ================== Ruby Interface part ==========================
214
201
*/
@@ -281,20 +268,6 @@ rbd_allocate_struct_zero_wrap(int sign, size_t const digits)
281
268
return (BDVALUE ) { BigDecimal_wrap_struct (rb_cBigDecimal , real ), real };
282
269
}
283
270
284
- // Only used in BigDecimal_sqrt
285
- MAYBE_UNUSED (static inline BDVALUE rbd_allocate_struct_zero_limited_wrap (int sign , size_t const digits ));
286
- #define NewZeroWrapLimited rbd_allocate_struct_zero_limited_wrap
287
- static inline BDVALUE
288
- rbd_allocate_struct_zero_limited_wrap (int sign , size_t digits )
289
- {
290
- size_t prec_limit = VpGetPrecLimit ();
291
- if (prec_limit ) {
292
- prec_limit += 2 * BASE_FIG ; /* 2 more digits for rounding and division */
293
- if (prec_limit < digits ) digits = prec_limit ;
294
- }
295
- return rbd_allocate_struct_zero_wrap (sign , digits );
296
- }
297
-
298
271
static inline int
299
272
is_kind_of_BigDecimal (VALUE const v )
300
273
{
@@ -2090,32 +2063,6 @@ BigDecimal_abs(VALUE self)
2090
2063
return CheckGetValue (c );
2091
2064
}
2092
2065
2093
- /* call-seq:
2094
- * sqrt(n)
2095
- *
2096
- * Returns the square root of the value.
2097
- *
2098
- * Result has at least n significant digits.
2099
- */
2100
- static VALUE
2101
- BigDecimal_sqrt (VALUE self , VALUE nFig )
2102
- {
2103
- BDVALUE c , a ;
2104
- size_t mx , n ;
2105
-
2106
- a = GetBDValueMust (self );
2107
- mx = a .real -> Prec * (VpBaseFig () + 1 );
2108
-
2109
- n = check_int_precision (nFig );
2110
- n += VpDblFig () + VpBaseFig ();
2111
- if (mx <= n ) mx = n ;
2112
- c = NewZeroWrapLimited (1 , mx );
2113
- VpSqrt (c .real , a .real );
2114
-
2115
- RB_GC_GUARD (a .bigdecimal );
2116
- return CheckGetValue (c );
2117
- }
2118
-
2119
2066
/* Return the integer part of the number, as a BigDecimal.
2120
2067
*/
2121
2068
static VALUE
@@ -3603,7 +3550,6 @@ Init_bigdecimal(void)
3603
3550
rb_define_method (rb_cBigDecimal , "dup" , BigDecimal_clone , 0 );
3604
3551
rb_define_method (rb_cBigDecimal , "to_f" , BigDecimal_to_f , 0 );
3605
3552
rb_define_method (rb_cBigDecimal , "abs" , BigDecimal_abs , 0 );
3606
- rb_define_method (rb_cBigDecimal , "sqrt" , BigDecimal_sqrt , 1 );
3607
3553
rb_define_method (rb_cBigDecimal , "fix" , BigDecimal_fix , 0 );
3608
3554
rb_define_method (rb_cBigDecimal , "round" , BigDecimal_round , -1 );
3609
3555
rb_define_method (rb_cBigDecimal , "frac" , BigDecimal_frac , 0 );
@@ -3675,9 +3621,6 @@ static int gfDebug = 1; /* Debug switch */
3675
3621
#endif /* BIGDECIMAL_DEBUG */
3676
3622
3677
3623
static Real * VpConstOne ; /* constant 1.0 */
3678
- static Real * VpConstPt5 ; /* constant 0.5 */
3679
- #define maxnr 100UL /* Maximum iterations for calculating sqrt. */
3680
- /* used in VpSqrt() */
3681
3624
3682
3625
enum op_sw {
3683
3626
OP_SW_ADD = 1 , /* + */
@@ -4082,12 +4025,6 @@ VpInit(DECDIG BaseVal)
4082
4025
VpConstOne = NewZero (1 , 1 );
4083
4026
VpSetOne (VpConstOne );
4084
4027
4085
- /* Const 0.5 */
4086
- VpConstPt5 = NewZero (1 , 1 );
4087
- VpSetSign (VpConstPt5 , 1 );
4088
- VpConstPt5 -> exponent = 0 ;
4089
- VpConstPt5 -> frac [0 ] = 5 * BASE1 ;
4090
-
4091
4028
#ifdef BIGDECIMAL_DEBUG
4092
4029
gnAlloc = 0 ;
4093
4030
#endif /* BIGDECIMAL_DEBUG */
@@ -4892,7 +4829,6 @@ VpMult(Real *c, Real *a, Real *b)
4892
4829
size_t ind_as , ind_ae , ind_bs ;
4893
4830
DECDIG carry ;
4894
4831
DECDIG_DBL s ;
4895
- Real * w ;
4896
4832
4897
4833
if (!VpIsDefOP (c , a , b , OP_SW_MULT )) return 0 ; /* No significant digit */
4898
4834
@@ -4912,29 +4848,19 @@ VpMult(Real *c, Real *a, Real *b)
4912
4848
}
4913
4849
if (b -> Prec > a -> Prec ) {
4914
4850
/* Adjust so that digits(a)>digits(b) */
4915
- w = a ;
4851
+ Real * w = a ;
4916
4852
a = b ;
4917
4853
b = w ;
4918
4854
}
4919
- w = NULL ;
4920
4855
MxIndA = a -> Prec - 1 ;
4921
4856
MxIndB = b -> Prec - 1 ;
4922
4857
MxIndAB = a -> Prec + b -> Prec - 1 ;
4923
4858
4924
- // Only VpSqrt calls VpMult with insufficient precision
4925
- if (c -> MaxPrec < VPMULT_RESULT_PREC (a , b )) {
4926
- w = c ;
4927
- c = NewZero (1 , VPMULT_RESULT_PREC (a , b ) * BASE_FIG );
4928
- }
4929
-
4930
4859
/* set LHSV c info */
4931
4860
4932
4861
c -> exponent = a -> exponent ; /* set exponent */
4933
4862
VpSetSign (c , VpGetSign (a ) * VpGetSign (b )); /* set sign */
4934
- if (!AddExponent (c , b -> exponent )) {
4935
- if (w ) rbd_free_struct (c );
4936
- return 0 ;
4937
- }
4863
+ if (!AddExponent (c , b -> exponent )) return 0 ;
4938
4864
carry = 0 ;
4939
4865
nc = ind_c = MxIndAB ;
4940
4866
memset (c -> frac , 0 , (nc + 1 ) * sizeof (DECDIG )); /* Initialize c */
@@ -4982,11 +4908,6 @@ VpMult(Real *c, Real *a, Real *b)
4982
4908
}
4983
4909
}
4984
4910
VpNmlz (c );
4985
- if (w != NULL ) { /* free work variable */
4986
- VpAsgn (w , c , 10 );
4987
- rbd_free_struct (c );
4988
- c = w ;
4989
- }
4990
4911
4991
4912
Exit :
4992
4913
return c -> Prec * BASE_FIG ;
@@ -5888,174 +5809,6 @@ VpVtoD(double *d, SIGNED_VALUE *e, Real *m)
5888
5809
return f ;
5889
5810
}
5890
5811
5891
- /*
5892
- * m <- d
5893
- */
5894
- VP_EXPORT void
5895
- VpDtoV (Real * m , double d )
5896
- {
5897
- size_t ind_m , mm ;
5898
- SIGNED_VALUE ne ;
5899
- DECDIG i ;
5900
- double val , val2 ;
5901
-
5902
- if (isnan (d )) {
5903
- VpSetNaN (m );
5904
- goto Exit ;
5905
- }
5906
- if (isinf (d )) {
5907
- if (d > 0.0 ) VpSetPosInf (m );
5908
- else VpSetNegInf (m );
5909
- goto Exit ;
5910
- }
5911
-
5912
- if (d == 0.0 ) {
5913
- VpSetZero (m , 1 );
5914
- goto Exit ;
5915
- }
5916
- val = (d > 0. ) ? d : - d ;
5917
- ne = 0 ;
5918
- if (val >= 1.0 ) {
5919
- while (val >= 1.0 ) {
5920
- val /= (double )BASE ;
5921
- ++ ne ;
5922
- }
5923
- }
5924
- else {
5925
- val2 = 1.0 / (double )BASE ;
5926
- while (val < val2 ) {
5927
- val *= (double )BASE ;
5928
- -- ne ;
5929
- }
5930
- }
5931
- /* Now val = 0.xxxxx*BASE**ne */
5932
-
5933
- mm = m -> MaxPrec ;
5934
- memset (m -> frac , 0 , mm * sizeof (DECDIG ));
5935
- for (ind_m = 0 ; val > 0.0 && ind_m < mm ; ind_m ++ ) {
5936
- val *= (double )BASE ;
5937
- i = (DECDIG )val ;
5938
- val -= (double )i ;
5939
- m -> frac [ind_m ] = i ;
5940
- }
5941
- if (ind_m >= mm ) ind_m = mm - 1 ;
5942
- VpSetSign (m , (d > 0.0 ) ? 1 : -1 );
5943
- m -> Prec = ind_m + 1 ;
5944
- m -> exponent = ne ;
5945
-
5946
- VpInternalRound (m , 0 , (m -> Prec > 0 ) ? m -> frac [m -> Prec - 1 ] : 0 ,
5947
- (DECDIG )(val * (double )BASE ));
5948
-
5949
- Exit :
5950
- return ;
5951
- }
5952
-
5953
- /*
5954
- * y = SQRT(x), y*y - x =>0
5955
- */
5956
- VP_EXPORT int
5957
- VpSqrt (Real * y , Real * x )
5958
- {
5959
- Real * f = NULL ;
5960
- Real * r = NULL ;
5961
- size_t y_prec ;
5962
- SIGNED_VALUE n , e ;
5963
- ssize_t nr ;
5964
- double val ;
5965
-
5966
- /* Zero or +Infinity ? */
5967
- if (VpIsZero (x ) || VpIsPosInf (x )) {
5968
- VpAsgn (y ,x ,1 );
5969
- goto Exit ;
5970
- }
5971
-
5972
- /* Negative ? */
5973
- if (BIGDECIMAL_NEGATIVE_P (x )) {
5974
- VpSetNaN (y );
5975
- return VpException (VP_EXCEPTION_OP , "sqrt of negative value" , 0 );
5976
- }
5977
-
5978
- /* NaN ? */
5979
- if (VpIsNaN (x )) {
5980
- VpSetNaN (y );
5981
- return VpException (VP_EXCEPTION_OP , "sqrt of 'NaN'(Not a Number)" , 0 );
5982
- }
5983
-
5984
- /* One ? */
5985
- if (VpIsOne (x )) {
5986
- VpSetOne (y );
5987
- goto Exit ;
5988
- }
5989
-
5990
- n = (SIGNED_VALUE )y -> MaxPrec ;
5991
- if (x -> MaxPrec > (size_t )n ) n = (ssize_t )x -> MaxPrec ;
5992
-
5993
- /* allocate temporally variables */
5994
- /* TODO: reconsider MaxPrec of f and r */
5995
- f = NewOneNolimit (1 , y -> MaxPrec * (BASE_FIG + 2 ));
5996
- r = NewOneNolimit (1 , (n + n ) * (BASE_FIG + 2 ));
5997
-
5998
- nr = 0 ;
5999
- y_prec = y -> MaxPrec ;
6000
-
6001
- VpVtoD (& val , & e , x ); /* val <- x */
6002
- e /= (SIGNED_VALUE )BASE_FIG ;
6003
- n = e / 2 ;
6004
- if (e - n * 2 != 0 ) {
6005
- val /= BASE ;
6006
- n = (e + 1 ) / 2 ;
6007
- }
6008
- VpDtoV (y , sqrt (val )); /* y <- sqrt(val) */
6009
- y -> exponent += n ;
6010
- n = (SIGNED_VALUE )roomof (BIGDECIMAL_DOUBLE_FIGURES , BASE_FIG );
6011
- y -> MaxPrec = Min ((size_t )n , y_prec );
6012
- f -> MaxPrec = y -> MaxPrec + 1 ;
6013
- n = (SIGNED_VALUE )(y_prec * BASE_FIG );
6014
- if (n > (SIGNED_VALUE )maxnr ) n = (SIGNED_VALUE )maxnr ;
6015
-
6016
- /*
6017
- * Perform: y_{n+1} = (y_n - x/y_n) / 2
6018
- */
6019
- do {
6020
- y -> MaxPrec *= 2 ;
6021
- if (y -> MaxPrec > y_prec ) y -> MaxPrec = y_prec ;
6022
- f -> MaxPrec = y -> MaxPrec ;
6023
- VpDivd (f , r , x , y ); /* f = x/y */
6024
- VpAddSub (r , f , y , -1 ); /* r = f - y */
6025
- VpMult (f , VpConstPt5 , r ); /* f = 0.5*r */
6026
- if (y_prec == y -> MaxPrec && VpIsZero (f ))
6027
- goto converge ;
6028
- VpAddSub (r , f , y , 1 ); /* r = y + f */
6029
- VpAsgn (y , r , 1 ); /* y = r */
6030
- } while (++ nr < n );
6031
-
6032
- #ifdef BIGDECIMAL_DEBUG
6033
- if (gfDebug ) {
6034
- printf ("ERROR(VpSqrt): did not converge within %ld iterations.\n" , nr );
6035
- }
6036
- #endif /* BIGDECIMAL_DEBUG */
6037
- y -> MaxPrec = y_prec ;
6038
-
6039
- converge :
6040
- VpChangeSign (y , 1 );
6041
- #ifdef BIGDECIMAL_DEBUG
6042
- if (gfDebug ) {
6043
- VpMult (r , y , y );
6044
- VpAddSub (f , x , r , -1 );
6045
- printf ("VpSqrt: iterations = %" PRIdSIZE "\n" , nr );
6046
- VPrint (stdout , " y =% \n" , y );
6047
- VPrint (stdout , " x =% \n" , x );
6048
- VPrint (stdout , " x-y*y = % \n" , f );
6049
- }
6050
- #endif /* BIGDECIMAL_DEBUG */
6051
- y -> MaxPrec = y_prec ;
6052
-
6053
- Exit :
6054
- rbd_free_struct (f );
6055
- rbd_free_struct (r );
6056
- return 1 ;
6057
- }
6058
-
6059
5812
/*
6060
5813
* Round relatively from the decimal point.
6061
5814
* f: rounding mode
0 commit comments