@@ -133,19 +133,43 @@ static inline void bc_standard_sqrt(bc_num *num, size_t rscale, size_t num_calc_
133133
134134 bc_convert_to_vector_with_zero_pad (n_vector , nend , n_full_len , n_extend_zeros );
135135
136- /* Prepare guess_vector (Temporary implementation) */
137- size_t guess_top_len = 0 ;
138- for (size_t i = 0 ; i < guess_arr_size - 2 ; i ++ ) {
139- guess_vector [i ] = BC_VECTOR_BOUNDARY_NUM - 1 ;
136+ /* Prepare guess_vector. Use `bc_fast_sqrt_vector()` to quickly obtain a highly accurate initial value. */
137+ size_t n_top_len_for_initial_guess = SIZEOF_SIZE_T == 8 ? 18 : 10 ;
138+
139+ /* Set the number of digits of num to be used as the initial value for Newton's method.
140+ * Just as the square roots of 1000 and 100 differ significantly, the number of digits
141+ * to "ignore" here must be even. */
142+ if (num_calc_full_len & 1 ) {
143+ n_top_len_for_initial_guess -- ;
140144 }
141- if (guess_full_len % BC_VECTOR_SIZE == 0 ) {
142- guess_vector [guess_arr_size - 2 ] = BC_VECTOR_BOUNDARY_NUM - 1 ;
143- } else {
144- guess_vector [guess_arr_size - 2 ] = 0 ;
145- for (size_t i = 0 ; i < guess_full_len % BC_VECTOR_SIZE ; i ++ ) {
146- guess_vector [guess_arr_size - 2 ] *= BASE ;
147- guess_vector [guess_arr_size - 2 ] += 9 ;
148- }
145+ BC_VECTOR n_top = n_vector [n_arr_size - 1 ];
146+ size_t n_top_index = n_arr_size - 2 ;
147+ size_t n_top_vector_len = num_calc_full_len % BC_VECTOR_SIZE == 0 ? BC_VECTOR_SIZE : num_calc_full_len % BC_VECTOR_SIZE ;
148+ size_t count = n_top_len_for_initial_guess - n_top_vector_len ;
149+ while (count >= BC_VECTOR_SIZE ) {
150+ n_top *= BC_VECTOR_BOUNDARY_NUM ;
151+ n_top += n_vector [n_top_index -- ];
152+ count -= BC_VECTOR_SIZE ;
153+ }
154+ if (count > 0 ) {
155+ n_top *= BC_POW_10_LUT [count ];
156+ n_top += n_vector [n_top_index ] / BC_POW_10_LUT [BC_VECTOR_SIZE - count ];
157+ }
158+
159+ /* Calculate the initial guess. */
160+ BC_VECTOR initial_guess = bc_fast_sqrt_vector (n_top );
161+
162+ /* Set the obtained initial guess to guess_vector. */
163+ size_t initial_guess_len = SIZEOF_SIZE_T == 8 ? 9 : 5 ;
164+ size_t guess_top_vector_len = guess_full_len % BC_VECTOR_SIZE == 0 ? BC_VECTOR_SIZE : guess_full_len % BC_VECTOR_SIZE ;
165+ size_t guess_len_diff = initial_guess_len - guess_top_vector_len ;
166+ guess_vector [guess_arr_size - 2 ] = initial_guess / BC_POW_10_LUT [guess_len_diff ];
167+ initial_guess %= BC_POW_10_LUT [guess_len_diff ];
168+ guess_vector [guess_arr_size - 3 ] = initial_guess * BC_POW_10_LUT [BC_VECTOR_SIZE - guess_len_diff ];
169+
170+ /* Initialize the uninitialized vector with zeros. */
171+ for (size_t i = 0 ; i < guess_arr_size - 3 ; i ++ ) {
172+ guess_vector [i ] = 0 ;
149173 }
150174 guess_vector [guess_arr_size - 1 ] = 0 ;
151175
0 commit comments