@ -18,7 +18,7 @@ static const cl_I digits_to_I_base2 (const char * MSBptr, uintC len, uintD base)
{
{
// base is a power of two: write the digits from least significant
// base is a power of two: write the digits from least significant
// to most significant into the result NUDS. Result needs
// to most significant into the result NUDS. Result needs
// 1+ceiling(len*log(base)/(intDsize*log(2))) or some more digits
// 1+ceiling(len*log(base)/(intDsize*log(2))) or some more digits.
CL_ALLOCA_STACK ;
CL_ALLOCA_STACK ;
var uintD * erg_MSDptr ;
var uintD * erg_MSDptr ;
var uintC erg_len ;
var uintC erg_len ;
@ -64,7 +64,7 @@ static const cl_I digits_to_I_base2 (const char * MSBptr, uintC len, uintD base)
static const cl_I digits_to_I_baseN ( const char * MSBptr , uintC len , uintD base )
static const cl_I digits_to_I_baseN ( const char * MSBptr , uintC len , uintD base )
{
{
// base is not a power of two: Add digits one by one. Result nees
// base is not a power of two: Add digits one by one. Result need s
// 1+ceiling(len*log(base)/(intDsize*log(2))) or some more digits.
// 1+ceiling(len*log(base)/(intDsize*log(2))) or some more digits.
CL_ALLOCA_STACK ;
CL_ALLOCA_STACK ;
var uintD * erg_MSDptr ;
var uintD * erg_MSDptr ;
@ -121,7 +121,6 @@ static const cl_I digits_to_I_baseN (const char * MSBptr, uintC len, uintD base)
var uintD factor = 1 ;
var uintD factor = 1 ;
while ( chx < power_table [ base - 2 ] . k & & len > 0 ) {
while ( chx < power_table [ base - 2 ] . k & & len > 0 ) {
var uintB ch = * ( const uintB * ) MSBptr ; MSBptr + + ; // next character
var uintB ch = * ( const uintB * ) MSBptr ; MSBptr + + ; // next character
if ( ch ! = ' . ' ) { // skip decimal point
// Compute value of ('0'-'9','A'-'Z','a'-'z'):
// Compute value of ('0'-'9','A'-'Z','a'-'z'):
ch = ch - ' 0 ' ;
ch = ch - ' 0 ' ;
if ( ch > ' 9 ' - ' 0 ' ) { // not a digit?
if ( ch > ' 9 ' - ' 0 ' ) { // not a digit?
@ -133,7 +132,6 @@ static const cl_I digits_to_I_baseN (const char * MSBptr, uintC len, uintD base)
factor = factor * base ;
factor = factor * base ;
newdigit = base * newdigit + ch ;
newdigit = base * newdigit + ch ;
chx + + ;
chx + + ;
}
len - - ;
len - - ;
}
}
var uintD carry = mulusmall_loop_lsp ( factor , erg_LSDptr , erg_len , newdigit ) ;
var uintD carry = mulusmall_loop_lsp ( factor , erg_LSDptr , erg_len , newdigit ) ;
@ -146,11 +144,8 @@ static const cl_I digits_to_I_baseN (const char * MSBptr, uintC len, uintD base)
return NUDS_to_I ( erg_MSDptr , erg_len ) ;
return NUDS_to_I ( erg_MSDptr , erg_len ) ;
}
}
const cl_I digits_to_I ( const char * MSBptr , uintC len , uintD base )
static const cl_I digits_to_I_divconq ( const char * MSBptr , uintC len , uintD base )
{
{
if ( ( base & ( base - 1 ) ) = = 0 ) {
return digits_to_I_base2 ( MSBptr , len , base ) ;
} else {
// This is quite insensitive to the breakeven point.
// This is quite insensitive to the breakeven point.
// On a 1GHz Athlon I get approximately:
// On a 1GHz Athlon I get approximately:
// base 3: breakeven around 25000
// base 3: breakeven around 25000
@ -167,12 +162,33 @@ const cl_I digits_to_I (const char * MSBptr, uintC len, uintD base)
break ;
break ;
len_B = len_B * 2 ;
len_B = len_B * 2 ;
}
}
return digits_to_I ( MSBptr , len - len_B , base ) * p - > base_pow
+ digits_to_I ( MSBptr + len - len_B , len_B , base ) ;
return digits_to_I_divconq ( MSBptr , len - len_B , base ) * p - > base_pow
+ digits_to_I_divconq ( MSBptr + len - len_B , len_B , base ) ;
} else {
} else {
return digits_to_I_baseN ( MSBptr , len , base ) ;
return digits_to_I_baseN ( MSBptr , len , base ) ;
}
}
}
}
const cl_I digits_to_I ( const char * MSBptr , uintC len , uintD base )
{
if ( ( base & ( base - 1 ) ) = = 0 ) {
return digits_to_I_base2 ( MSBptr , len , base ) ;
} else {
// digits_to_I_divconq cannot handle decimal points, so remove it here
CL_ALLOCA_STACK ;
const uintD * digits_copy ;
num_stack_alloc ( len , , digits_copy = ) ;
char * copy_ptr = ( char * ) digits_copy ;
uintC n = 0 ;
for ( uintC i = 0 ; i < len ; + + i ) {
const char ch = MSBptr [ i ] ;
if ( ch ! = ' . ' ) { // skip decimal point
copy_ptr [ n ] = ch ;
n + + ;
}
}
return digits_to_I_divconq ( ( const char * ) digits_copy , n , base ) ;
}
}
}
} // namespace cln
} // namespace cln