@@ -140,20 +140,34 @@ static inline void bc_standard_sqrt(bc_num *num, size_t rscale, size_t num_calc_
140
140
141
141
bc_convert_to_vector_with_zero_pad (n_vector , nend , n_full_len , n_extend_zeros );
142
142
143
- /* Prepare guess_vector (Temporary implementation) */
144
- for (size_t i = 0 ; i < guess_vector_size - 2 ; i ++ ) {
145
- guess_vector [i ] = BC_VECTOR_BOUNDARY_NUM - 1 ;
143
+ /* Prepare guess_vector. Use bc_fast_sqrt_vector to quickly obtain a highly accurate initial value. */
144
+ size_t n_top_len_for_initial_guess = SIZEOF_SIZE_T == 8 ? 18 : 10 ;
145
+
146
+ /* Set the number of digits of num to be used as the initial value for Newton's method.
147
+ * Just as the square roots of 1000 and 100 differ significantly, the number of digits
148
+ * to "ignore" here must be even. */
149
+ if (num_calc_full_len & 1 ) {
150
+ n_top_len_for_initial_guess -- ;
146
151
}
147
- if (guess_full_len % BC_VECTOR_SIZE == 0 ) {
148
- guess_vector [guess_vector_size - 2 ] = BC_VECTOR_BOUNDARY_NUM - 1 ;
149
- } else {
150
- guess_vector [guess_vector_size - 2 ] = 0 ;
151
- for (size_t i = 0 ; i < guess_full_len % BC_VECTOR_SIZE ; i ++ ) {
152
- guess_vector [guess_vector_size - 2 ] *= BASE ;
153
- guess_vector [guess_vector_size - 2 ] += 9 ;
154
- }
152
+ const char * nptr = (* num )-> n_value ;
153
+ BC_VECTOR n_top = 0 ;
154
+ for (size_t i = 0 ; i < n_top_len_for_initial_guess ; i ++ ) {
155
+ n_top *= BASE ;
156
+ n_top += * nptr ++ ;
157
+ }
158
+
159
+ for (size_t i = 0 ; i < guess_vector_size ; i ++ ) {
160
+ guess_vector [i ] = 0 ;
155
161
}
156
- guess_vector [guess_vector_size - 1 ] = 0 ;
162
+ BC_VECTOR initial_guess = bc_fast_sqrt_vector (n_top );
163
+
164
+ size_t initial_guess_len = SIZEOF_SIZE_T == 8 ? 9 : 5 ;
165
+ size_t guess_top_vector_len = guess_full_len % BC_VECTOR_SIZE == 0 ? BC_VECTOR_SIZE : guess_full_len % BC_VECTOR_SIZE ;
166
+ size_t guess_len_diff = initial_guess_len - guess_top_vector_len ;
167
+ guess_vector [guess_vector_size - 2 ] = initial_guess / BC_POW_10_LUT [guess_len_diff ];
168
+ initial_guess %= BC_POW_10_LUT [guess_len_diff ];
169
+ guess_vector [guess_vector_size - 3 ] = initial_guess * BC_POW_10_LUT [BC_VECTOR_SIZE - guess_len_diff ];
170
+
157
171
guess1_vector [guess_vector_size - 1 ] = 0 ;
158
172
159
173
size_t quot_size = n_vector_size - (guess_vector_size - 1 ) + 1 ;
0 commit comments