@@ -1303,6 +1303,14 @@ impl Program {
1303
1303
state. registers [ * dest] = result;
1304
1304
state. pc += 1 ;
1305
1305
}
1306
+ SingleRowFunc :: Round => {
1307
+ let start_reg = * start_reg;
1308
+ let reg_value = state. registers [ start_reg] . clone ( ) ;
1309
+ let precision_value = state. registers . get ( start_reg + 1 ) . cloned ( ) ;
1310
+ let result = exec_round ( & reg_value, precision_value) ;
1311
+ state. registers [ * dest] = result;
1312
+ state. pc += 1 ;
1313
+ }
1306
1314
} ,
1307
1315
}
1308
1316
}
@@ -1888,6 +1896,27 @@ fn exec_like(pattern: &str, text: &str) -> bool {
1888
1896
re. is_match ( text)
1889
1897
}
1890
1898
1899
+ fn exec_round ( reg : & OwnedValue , precision : Option < OwnedValue > ) -> OwnedValue {
1900
+ let precision = match precision {
1901
+ Some ( OwnedValue :: Text ( x) ) => x. parse ( ) . unwrap_or ( 0.0 ) ,
1902
+ Some ( OwnedValue :: Integer ( x) ) => x as f64 ,
1903
+ Some ( OwnedValue :: Float ( x) ) => x,
1904
+ None => 0.0 ,
1905
+ _ => return OwnedValue :: Null ,
1906
+ } ;
1907
+
1908
+ let reg = match reg {
1909
+ OwnedValue :: Text ( x) => x. parse ( ) . unwrap_or ( 0.0 ) ,
1910
+ OwnedValue :: Integer ( x) => * x as f64 ,
1911
+ OwnedValue :: Float ( x) => * x,
1912
+ _ => return reg. to_owned ( ) ,
1913
+ } ;
1914
+
1915
+ let precision = if precision < 1.0 { 0.0 } else { precision } ;
1916
+ let multiplier = 10f64 . powi ( precision as i32 ) ;
1917
+ OwnedValue :: Float ( ( ( reg * multiplier) . round ( ) ) / multiplier)
1918
+ }
1919
+
1891
1920
// Implements TRIM pattern matching.
1892
1921
fn exec_trim ( reg : & OwnedValue , pattern : Option < OwnedValue > ) -> OwnedValue {
1893
1922
match ( reg, pattern) {
@@ -1922,7 +1951,8 @@ fn exec_if(reg: &OwnedValue, null_reg: &OwnedValue, not: bool) -> bool {
1922
1951
#[ cfg( test) ]
1923
1952
mod tests {
1924
1953
use super :: {
1925
- exec_abs, exec_if, exec_like, exec_lower, exec_random, exec_trim, exec_upper, OwnedValue ,
1954
+ exec_abs, exec_if, exec_like, exec_lower, exec_random, exec_round, exec_trim, exec_upper,
1955
+ OwnedValue ,
1926
1956
} ;
1927
1957
use std:: rc:: Rc ;
1928
1958
@@ -2001,6 +2031,33 @@ mod tests {
2001
2031
}
2002
2032
}
2003
2033
2034
+ #[ test]
2035
+ fn test_exec_round ( ) {
2036
+ let input_val = OwnedValue :: Float ( 123.456 ) ;
2037
+ let expected_val = OwnedValue :: Float ( 123.0 ) ;
2038
+ assert_eq ! ( exec_round( & input_val, None ) , expected_val) ;
2039
+
2040
+ let input_val = OwnedValue :: Float ( 123.456 ) ;
2041
+ let precision_val = OwnedValue :: Integer ( 2 ) ;
2042
+ let expected_val = OwnedValue :: Float ( 123.46 ) ;
2043
+ assert_eq ! ( exec_round( & input_val, Some ( precision_val) ) , expected_val) ;
2044
+
2045
+ let input_val = OwnedValue :: Float ( 123.456 ) ;
2046
+ let precision_val = OwnedValue :: Text ( Rc :: new ( String :: from ( "1" ) ) ) ;
2047
+ let expected_val = OwnedValue :: Float ( 123.5 ) ;
2048
+ assert_eq ! ( exec_round( & input_val, Some ( precision_val) ) , expected_val) ;
2049
+
2050
+ let input_val = OwnedValue :: Text ( Rc :: new ( String :: from ( "123.456" ) ) ) ;
2051
+ let precision_val = OwnedValue :: Integer ( 2 ) ;
2052
+ let expected_val = OwnedValue :: Float ( 123.46 ) ;
2053
+ assert_eq ! ( exec_round( & input_val, Some ( precision_val) ) , expected_val) ;
2054
+
2055
+ let input_val = OwnedValue :: Integer ( 123 ) ;
2056
+ let precision_val = OwnedValue :: Integer ( 1 ) ;
2057
+ let expected_val = OwnedValue :: Float ( 123.0 ) ;
2058
+ assert_eq ! ( exec_round( & input_val, Some ( precision_val) ) , expected_val) ;
2059
+ }
2060
+
2004
2061
#[ test]
2005
2062
fn test_exec_if ( ) {
2006
2063
let reg = OwnedValue :: Integer ( 0 ) ;
0 commit comments