@@ -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
{
@@ -2081,32 +2054,6 @@ BigDecimal_abs(VALUE self)
2081
2054
return CheckGetValue (c );
2082
2055
}
2083
2056
2084
- /* call-seq:
2085
- * sqrt(n)
2086
- *
2087
- * Returns the square root of the value.
2088
- *
2089
- * Result has at least n significant digits.
2090
- */
2091
- static VALUE
2092
- BigDecimal_sqrt (VALUE self , VALUE nFig )
2093
- {
2094
- BDVALUE c , a ;
2095
- size_t mx , n ;
2096
-
2097
- a = GetBDValueMust (self );
2098
- mx = a .real -> Prec * (VpBaseFig () + 1 );
2099
-
2100
- n = check_int_precision (nFig );
2101
- n += VpDblFig () + VpBaseFig ();
2102
- if (mx <= n ) mx = n ;
2103
- c = NewZeroWrapLimited (1 , mx );
2104
- VpSqrt (c .real , a .real );
2105
-
2106
- RB_GC_GUARD (a .bigdecimal );
2107
- return CheckGetValue (c );
2108
- }
2109
-
2110
2057
/* Return the integer part of the number, as a BigDecimal.
2111
2058
*/
2112
2059
static VALUE
@@ -3594,7 +3541,6 @@ Init_bigdecimal(void)
3594
3541
rb_define_method (rb_cBigDecimal , "dup" , BigDecimal_clone , 0 );
3595
3542
rb_define_method (rb_cBigDecimal , "to_f" , BigDecimal_to_f , 0 );
3596
3543
rb_define_method (rb_cBigDecimal , "abs" , BigDecimal_abs , 0 );
3597
- rb_define_method (rb_cBigDecimal , "sqrt" , BigDecimal_sqrt , 1 );
3598
3544
rb_define_method (rb_cBigDecimal , "fix" , BigDecimal_fix , 0 );
3599
3545
rb_define_method (rb_cBigDecimal , "round" , BigDecimal_round , -1 );
3600
3546
rb_define_method (rb_cBigDecimal , "frac" , BigDecimal_frac , 0 );
@@ -3666,9 +3612,6 @@ static int gfDebug = 1; /* Debug switch */
3666
3612
#endif /* BIGDECIMAL_DEBUG */
3667
3613
3668
3614
static Real * VpConstOne ; /* constant 1.0 */
3669
- static Real * VpConstPt5 ; /* constant 0.5 */
3670
- #define maxnr 100UL /* Maximum iterations for calculating sqrt. */
3671
- /* used in VpSqrt() */
3672
3615
3673
3616
enum op_sw {
3674
3617
OP_SW_ADD = 1 , /* + */
@@ -4073,12 +4016,6 @@ VpInit(DECDIG BaseVal)
4073
4016
VpConstOne = NewZero (1 , 1 );
4074
4017
VpSetOne (VpConstOne );
4075
4018
4076
- /* Const 0.5 */
4077
- VpConstPt5 = NewZero (1 , 1 );
4078
- VpSetSign (VpConstPt5 , 1 );
4079
- VpConstPt5 -> exponent = 0 ;
4080
- VpConstPt5 -> frac [0 ] = 5 * BASE1 ;
4081
-
4082
4019
#ifdef BIGDECIMAL_DEBUG
4083
4020
gnAlloc = 0 ;
4084
4021
#endif /* BIGDECIMAL_DEBUG */
@@ -4883,7 +4820,6 @@ VpMult(Real *c, Real *a, Real *b)
4883
4820
size_t ind_as , ind_ae , ind_bs ;
4884
4821
DECDIG carry ;
4885
4822
DECDIG_DBL s ;
4886
- Real * w ;
4887
4823
4888
4824
if (!VpIsDefOP (c , a , b , OP_SW_MULT )) return 0 ; /* No significant digit */
4889
4825
@@ -4903,29 +4839,19 @@ VpMult(Real *c, Real *a, Real *b)
4903
4839
}
4904
4840
if (b -> Prec > a -> Prec ) {
4905
4841
/* Adjust so that digits(a)>digits(b) */
4906
- w = a ;
4842
+ Real * w = a ;
4907
4843
a = b ;
4908
4844
b = w ;
4909
4845
}
4910
- w = NULL ;
4911
4846
MxIndA = a -> Prec - 1 ;
4912
4847
MxIndB = b -> Prec - 1 ;
4913
4848
MxIndAB = a -> Prec + b -> Prec - 1 ;
4914
4849
4915
- // Only VpSqrt calls VpMult with insufficient precision
4916
- if (c -> MaxPrec < VPMULT_RESULT_PREC (a , b )) {
4917
- w = c ;
4918
- c = NewZero (1 , VPMULT_RESULT_PREC (a , b ) * BASE_FIG );
4919
- }
4920
-
4921
4850
/* set LHSV c info */
4922
4851
4923
4852
c -> exponent = a -> exponent ; /* set exponent */
4924
4853
VpSetSign (c , VpGetSign (a ) * VpGetSign (b )); /* set sign */
4925
- if (!AddExponent (c , b -> exponent )) {
4926
- if (w ) rbd_free_struct (c );
4927
- return 0 ;
4928
- }
4854
+ if (!AddExponent (c , b -> exponent )) return 0 ;
4929
4855
carry = 0 ;
4930
4856
nc = ind_c = MxIndAB ;
4931
4857
memset (c -> frac , 0 , (nc + 1 ) * sizeof (DECDIG )); /* Initialize c */
@@ -4973,11 +4899,6 @@ VpMult(Real *c, Real *a, Real *b)
4973
4899
}
4974
4900
}
4975
4901
VpNmlz (c );
4976
- if (w != NULL ) { /* free work variable */
4977
- VpAsgn (w , c , 10 );
4978
- rbd_free_struct (c );
4979
- c = w ;
4980
- }
4981
4902
4982
4903
Exit :
4983
4904
return c -> Prec * BASE_FIG ;
@@ -5879,174 +5800,6 @@ VpVtoD(double *d, SIGNED_VALUE *e, Real *m)
5879
5800
return f ;
5880
5801
}
5881
5802
5882
- /*
5883
- * m <- d
5884
- */
5885
- VP_EXPORT void
5886
- VpDtoV (Real * m , double d )
5887
- {
5888
- size_t ind_m , mm ;
5889
- SIGNED_VALUE ne ;
5890
- DECDIG i ;
5891
- double val , val2 ;
5892
-
5893
- if (isnan (d )) {
5894
- VpSetNaN (m );
5895
- goto Exit ;
5896
- }
5897
- if (isinf (d )) {
5898
- if (d > 0.0 ) VpSetPosInf (m );
5899
- else VpSetNegInf (m );
5900
- goto Exit ;
5901
- }
5902
-
5903
- if (d == 0.0 ) {
5904
- VpSetZero (m , 1 );
5905
- goto Exit ;
5906
- }
5907
- val = (d > 0. ) ? d : - d ;
5908
- ne = 0 ;
5909
- if (val >= 1.0 ) {
5910
- while (val >= 1.0 ) {
5911
- val /= (double )BASE ;
5912
- ++ ne ;
5913
- }
5914
- }
5915
- else {
5916
- val2 = 1.0 / (double )BASE ;
5917
- while (val < val2 ) {
5918
- val *= (double )BASE ;
5919
- -- ne ;
5920
- }
5921
- }
5922
- /* Now val = 0.xxxxx*BASE**ne */
5923
-
5924
- mm = m -> MaxPrec ;
5925
- memset (m -> frac , 0 , mm * sizeof (DECDIG ));
5926
- for (ind_m = 0 ; val > 0.0 && ind_m < mm ; ind_m ++ ) {
5927
- val *= (double )BASE ;
5928
- i = (DECDIG )val ;
5929
- val -= (double )i ;
5930
- m -> frac [ind_m ] = i ;
5931
- }
5932
- if (ind_m >= mm ) ind_m = mm - 1 ;
5933
- VpSetSign (m , (d > 0.0 ) ? 1 : -1 );
5934
- m -> Prec = ind_m + 1 ;
5935
- m -> exponent = ne ;
5936
-
5937
- VpInternalRound (m , 0 , (m -> Prec > 0 ) ? m -> frac [m -> Prec - 1 ] : 0 ,
5938
- (DECDIG )(val * (double )BASE ));
5939
-
5940
- Exit :
5941
- return ;
5942
- }
5943
-
5944
- /*
5945
- * y = SQRT(x), y*y - x =>0
5946
- */
5947
- VP_EXPORT int
5948
- VpSqrt (Real * y , Real * x )
5949
- {
5950
- Real * f = NULL ;
5951
- Real * r = NULL ;
5952
- size_t y_prec ;
5953
- SIGNED_VALUE n , e ;
5954
- ssize_t nr ;
5955
- double val ;
5956
-
5957
- /* Zero or +Infinity ? */
5958
- if (VpIsZero (x ) || VpIsPosInf (x )) {
5959
- VpAsgn (y ,x ,1 );
5960
- goto Exit ;
5961
- }
5962
-
5963
- /* Negative ? */
5964
- if (BIGDECIMAL_NEGATIVE_P (x )) {
5965
- VpSetNaN (y );
5966
- return VpException (VP_EXCEPTION_OP , "sqrt of negative value" , 0 );
5967
- }
5968
-
5969
- /* NaN ? */
5970
- if (VpIsNaN (x )) {
5971
- VpSetNaN (y );
5972
- return VpException (VP_EXCEPTION_OP , "sqrt of 'NaN'(Not a Number)" , 0 );
5973
- }
5974
-
5975
- /* One ? */
5976
- if (VpIsOne (x )) {
5977
- VpSetOne (y );
5978
- goto Exit ;
5979
- }
5980
-
5981
- n = (SIGNED_VALUE )y -> MaxPrec ;
5982
- if (x -> MaxPrec > (size_t )n ) n = (ssize_t )x -> MaxPrec ;
5983
-
5984
- /* allocate temporally variables */
5985
- /* TODO: reconsider MaxPrec of f and r */
5986
- f = NewOneNolimit (1 , y -> MaxPrec * (BASE_FIG + 2 ));
5987
- r = NewOneNolimit (1 , (n + n ) * (BASE_FIG + 2 ));
5988
-
5989
- nr = 0 ;
5990
- y_prec = y -> MaxPrec ;
5991
-
5992
- VpVtoD (& val , & e , x ); /* val <- x */
5993
- e /= (SIGNED_VALUE )BASE_FIG ;
5994
- n = e / 2 ;
5995
- if (e - n * 2 != 0 ) {
5996
- val /= BASE ;
5997
- n = (e + 1 ) / 2 ;
5998
- }
5999
- VpDtoV (y , sqrt (val )); /* y <- sqrt(val) */
6000
- y -> exponent += n ;
6001
- n = (SIGNED_VALUE )roomof (BIGDECIMAL_DOUBLE_FIGURES , BASE_FIG );
6002
- y -> MaxPrec = Min ((size_t )n , y_prec );
6003
- f -> MaxPrec = y -> MaxPrec + 1 ;
6004
- n = (SIGNED_VALUE )(y_prec * BASE_FIG );
6005
- if (n > (SIGNED_VALUE )maxnr ) n = (SIGNED_VALUE )maxnr ;
6006
-
6007
- /*
6008
- * Perform: y_{n+1} = (y_n - x/y_n) / 2
6009
- */
6010
- do {
6011
- y -> MaxPrec *= 2 ;
6012
- if (y -> MaxPrec > y_prec ) y -> MaxPrec = y_prec ;
6013
- f -> MaxPrec = y -> MaxPrec ;
6014
- VpDivd (f , r , x , y ); /* f = x/y */
6015
- VpAddSub (r , f , y , -1 ); /* r = f - y */
6016
- VpMult (f , VpConstPt5 , r ); /* f = 0.5*r */
6017
- if (y_prec == y -> MaxPrec && VpIsZero (f ))
6018
- goto converge ;
6019
- VpAddSub (r , f , y , 1 ); /* r = y + f */
6020
- VpAsgn (y , r , 1 ); /* y = r */
6021
- } while (++ nr < n );
6022
-
6023
- #ifdef BIGDECIMAL_DEBUG
6024
- if (gfDebug ) {
6025
- printf ("ERROR(VpSqrt): did not converge within %ld iterations.\n" , nr );
6026
- }
6027
- #endif /* BIGDECIMAL_DEBUG */
6028
- y -> MaxPrec = y_prec ;
6029
-
6030
- converge :
6031
- VpChangeSign (y , 1 );
6032
- #ifdef BIGDECIMAL_DEBUG
6033
- if (gfDebug ) {
6034
- VpMult (r , y , y );
6035
- VpAddSub (f , x , r , -1 );
6036
- printf ("VpSqrt: iterations = %" PRIdSIZE "\n" , nr );
6037
- VPrint (stdout , " y =% \n" , y );
6038
- VPrint (stdout , " x =% \n" , x );
6039
- VPrint (stdout , " x-y*y = % \n" , f );
6040
- }
6041
- #endif /* BIGDECIMAL_DEBUG */
6042
- y -> MaxPrec = y_prec ;
6043
-
6044
- Exit :
6045
- rbd_free_struct (f );
6046
- rbd_free_struct (r );
6047
- return 1 ;
6048
- }
6049
-
6050
5803
/*
6051
5804
* Round relatively from the decimal point.
6052
5805
* f: rounding mode
0 commit comments