@@ -102,32 +102,39 @@ impl LogFunc {
102102 }
103103}
104104
105- /// Binary function to calculate an integer logarithm of Decimal128 `value` using `base` base
106- /// Returns error if base is invalid
107105fn log_decimal128 ( value : i128 , scale : i8 , base : f64 ) -> Result < f64 , ArrowError > {
108- if !base. is_finite ( ) || base . trunc ( ) != base {
106+ if !base. is_finite ( ) {
109107 return Err ( ArrowError :: ComputeError ( format ! (
110- "Log cannot use non-integer base: {base}"
108+ "Log cannot use non-finite base: {base}"
111109 ) ) ) ;
112110 }
113- if ( base as u32 ) < 2 {
111+ if base <= 1.0 {
114112 return Err ( ArrowError :: ComputeError ( format ! (
115113 "Log base must be greater than 1: {base}"
116114 ) ) ) ;
117115 }
118116
119- let unscaled_value = decimal128_to_i128 ( value, scale) ?;
120- if unscaled_value > 0 {
121- let log_value: u32 = unscaled_value. ilog ( base as i128 ) ;
122- Ok ( log_value as f64 )
117+ // For integer bases >= 2, use the efficient integer algorithm
118+ if base. trunc ( ) == base && base >= 2.0 && base <= u32:: MAX as f64 {
119+ let unscaled_value = decimal128_to_i128 ( value, scale) ?;
120+ if unscaled_value > 0 {
121+ let log_value: u32 = unscaled_value. ilog ( base as i128 ) ;
122+ return Ok ( log_value as f64 ) ;
123+ } else {
124+ return Ok ( f64:: NAN ) ;
125+ }
126+ }
127+
128+ // For non-integer bases, fallback to f64 computation
129+ let scale_factor = 10f64 . powi ( scale as i32 ) ;
130+ let value_f64 = ( value as f64 ) / scale_factor;
131+ if value_f64 > 0.0 {
132+ Ok ( value_f64. log ( base) )
123133 } else {
124- // Reflect f64::log behaviour
125134 Ok ( f64:: NAN )
126135 }
127136}
128137
129- /// Binary function to calculate an integer logarithm of Decimal128 `value` using `base` base
130- /// Returns error if base is invalid or if value is out of bounds of Decimal128
131138fn log_decimal256 ( value : i256 , scale : i8 , base : f64 ) -> Result < f64 , ArrowError > {
132139 match value. to_i128 ( ) {
133140 Some ( value) => log_decimal128 ( value, scale, base) ,
0 commit comments