Skip to content

Commit fbd493f

Browse files
committed
schubfach
1 parent 955f739 commit fbd493f

File tree

3 files changed

+1537
-4
lines changed

3 files changed

+1537
-4
lines changed

native/spark-expr/src/conversion_funcs/cast.rs

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
// specific language governing permissions and limitations
1616
// under the License.
1717

18+
use crate::conversion_funcs::schubfach;
1819
use crate::timezone;
1920
use crate::utils::array_with_timezone;
2021
use crate::{EvalMode, SparkError, SparkResult};
@@ -49,6 +50,7 @@ use num::{
4950
ToPrimitive,
5051
};
5152
use regex::Regex;
53+
use std::num::Saturating;
5254
use std::str::FromStr;
5355
use std::{
5456
any::Any,
@@ -1278,17 +1280,29 @@ where
12781280
let input = array.as_any().downcast_ref::<PrimitiveArray<T>>().unwrap();
12791281
let mut cast_array = PrimitiveArray::<Decimal128Type>::builder(input.len());
12801282

1281-
let mul = 10_f64.powi(scale as i32);
1282-
12831283
for i in 0..input.len() {
12841284
if input.is_null(i) {
12851285
cast_array.append_null();
12861286
} else {
12871287
let input_value = input.value(i).as_();
1288-
let value = (input_value * mul).round().to_i128();
1288+
let value = schubfach::to_decimal(input_value);
12891289

12901290
match value {
1291-
Some(v) => {
1291+
Some((significand, exponent)) => {
1292+
let mut v = if input_value < 0. {
1293+
-significand
1294+
} else {
1295+
significand
1296+
} as i128;
1297+
1298+
let k = exponent + scale as i32;
1299+
if k > 0 {
1300+
v = v.saturating_mul(Saturating(10_i128).pow(k as u32).0);
1301+
} else if k < 0 {
1302+
let dk = Saturating(10_i128).pow((-k) as u32).0;
1303+
let (div, rem) = if dk < v { v.div_rem(&dk) } else { (0, v) };
1304+
v = if rem * 2 >= dk { div + 1 } else { div };
1305+
}
12921306
if Decimal128Type::validate_decimal_precision(v, precision).is_err() {
12931307
if eval_mode == EvalMode::Ansi {
12941308
return Err(SparkError::NumericValueOutOfRange {

native/spark-expr/src/conversion_funcs/mod.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,3 +16,5 @@
1616
// under the License.
1717

1818
pub mod cast;
19+
20+
mod schubfach;

0 commit comments

Comments
 (0)