UPDATE: Adds a bunch of mathematical functions (#496)
This commit is contained in:
committed by
GitHub
parent
c8ae835bbe
commit
b2d848ae2a
@@ -848,6 +848,20 @@ fn get_function_args_signature(kind: &Function, arg_count: usize) -> Vec<Signatu
|
|||||||
Function::Sign => args_signature_scalars(arg_count, 1, 0),
|
Function::Sign => args_signature_scalars(arg_count, 1, 0),
|
||||||
Function::Radians => args_signature_scalars(arg_count, 1, 0),
|
Function::Radians => args_signature_scalars(arg_count, 1, 0),
|
||||||
Function::Degrees => args_signature_scalars(arg_count, 1, 0),
|
Function::Degrees => args_signature_scalars(arg_count, 1, 0),
|
||||||
|
Function::Int => args_signature_scalars(arg_count, 1, 0),
|
||||||
|
Function::Even => args_signature_scalars(arg_count, 1, 0),
|
||||||
|
Function::Odd => args_signature_scalars(arg_count, 1, 0),
|
||||||
|
Function::Ceiling => args_signature_scalars(arg_count, 2, 0), // (number, significance)
|
||||||
|
Function::CeilingMath => args_signature_scalars(arg_count, 1, 2), // (number, [significance], [mode])
|
||||||
|
Function::CeilingPrecise => args_signature_scalars(arg_count, 1, 1), // (number, [significance])
|
||||||
|
Function::Floor => args_signature_scalars(arg_count, 2, 0), // (number, significance)
|
||||||
|
Function::FloorMath => args_signature_scalars(arg_count, 1, 2), // (number, [significance], [mode])
|
||||||
|
Function::FloorPrecise => args_signature_scalars(arg_count, 1, 1), // (number, [significance])
|
||||||
|
Function::IsoCeiling => args_signature_scalars(arg_count, 1, 1), // (number, [significance])
|
||||||
|
Function::Mod => args_signature_scalars(arg_count, 2, 0), // (number, divisor)
|
||||||
|
Function::Quotient => args_signature_scalars(arg_count, 2, 0), // (number, denominator)
|
||||||
|
Function::Mround => args_signature_scalars(arg_count, 2, 0), // (number, multiple)
|
||||||
|
Function::Trunc => args_signature_scalars(arg_count, 1, 1), // (num, [num_digits])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1084,5 +1098,19 @@ fn static_analysis_on_function(kind: &Function, args: &[Node]) -> StaticResult {
|
|||||||
Function::Sign => scalar_arguments(args),
|
Function::Sign => scalar_arguments(args),
|
||||||
Function::Radians => scalar_arguments(args),
|
Function::Radians => scalar_arguments(args),
|
||||||
Function::Degrees => scalar_arguments(args),
|
Function::Degrees => scalar_arguments(args),
|
||||||
|
Function::Int => scalar_arguments(args),
|
||||||
|
Function::Even => scalar_arguments(args),
|
||||||
|
Function::Odd => scalar_arguments(args),
|
||||||
|
Function::Ceiling => scalar_arguments(args),
|
||||||
|
Function::CeilingMath => scalar_arguments(args),
|
||||||
|
Function::CeilingPrecise => scalar_arguments(args),
|
||||||
|
Function::Floor => scalar_arguments(args),
|
||||||
|
Function::FloorMath => scalar_arguments(args),
|
||||||
|
Function::FloorPrecise => scalar_arguments(args),
|
||||||
|
Function::IsoCeiling => scalar_arguments(args),
|
||||||
|
Function::Mod => scalar_arguments(args),
|
||||||
|
Function::Quotient => scalar_arguments(args),
|
||||||
|
Function::Mround => scalar_arguments(args),
|
||||||
|
Function::Trunc => scalar_arguments(args),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -381,6 +381,317 @@ impl Model {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// (number, divisor)
|
||||||
|
pub(crate) fn fn_mod(&mut self, args: &[Node], cell: CellReferenceIndex) -> CalcResult {
|
||||||
|
if args.len() != 2 {
|
||||||
|
return CalcResult::new_args_number_error(cell);
|
||||||
|
}
|
||||||
|
let value = match self.get_number(&args[0], cell) {
|
||||||
|
Ok(f) => f,
|
||||||
|
Err(s) => return s,
|
||||||
|
};
|
||||||
|
let divisor = match self.get_number(&args[1], cell) {
|
||||||
|
Ok(f) => f,
|
||||||
|
Err(s) => return s,
|
||||||
|
};
|
||||||
|
if divisor == 0.0 {
|
||||||
|
return CalcResult::Error {
|
||||||
|
error: Error::DIV,
|
||||||
|
origin: cell,
|
||||||
|
message: "Divide by 0".to_string(),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
let result = value - divisor * (value / divisor).floor();
|
||||||
|
CalcResult::Number(result)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn fn_quotient(&mut self, args: &[Node], cell: CellReferenceIndex) -> CalcResult {
|
||||||
|
if args.len() != 2 {
|
||||||
|
return CalcResult::new_args_number_error(cell);
|
||||||
|
}
|
||||||
|
let value = match self.get_number(&args[0], cell) {
|
||||||
|
Ok(f) => f,
|
||||||
|
Err(s) => return s,
|
||||||
|
};
|
||||||
|
let divisor = match self.get_number(&args[1], cell) {
|
||||||
|
Ok(f) => f,
|
||||||
|
Err(s) => return s,
|
||||||
|
};
|
||||||
|
if divisor == 0.0 {
|
||||||
|
return CalcResult::Error {
|
||||||
|
error: Error::DIV,
|
||||||
|
origin: cell,
|
||||||
|
message: "Divide by 0".to_string(),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
let result = value / divisor;
|
||||||
|
CalcResult::Number(result.signum() * result.abs().floor())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn fn_floor(&mut self, args: &[Node], cell: CellReferenceIndex) -> CalcResult {
|
||||||
|
if args.len() != 2 {
|
||||||
|
return CalcResult::new_args_number_error(cell);
|
||||||
|
}
|
||||||
|
let value = match self.get_number(&args[0], cell) {
|
||||||
|
Ok(f) => f,
|
||||||
|
Err(s) => return s,
|
||||||
|
};
|
||||||
|
let significance = match self.get_number(&args[1], cell) {
|
||||||
|
Ok(f) => f,
|
||||||
|
Err(s) => return s,
|
||||||
|
};
|
||||||
|
if significance == 0.0 {
|
||||||
|
if value == 0.0 {
|
||||||
|
return CalcResult::Number(0.0);
|
||||||
|
}
|
||||||
|
return CalcResult::Error {
|
||||||
|
error: Error::DIV,
|
||||||
|
origin: cell,
|
||||||
|
message: "Divide by 0".to_string(),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
if significance < 0.0 && value > 0.0 {
|
||||||
|
return CalcResult::Error {
|
||||||
|
error: Error::NUM,
|
||||||
|
origin: cell,
|
||||||
|
message: "Significance must be positive when value is positive".to_string(),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
let result = f64::floor(value / significance) * significance;
|
||||||
|
CalcResult::Number(result)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn fn_ceiling(&mut self, args: &[Node], cell: CellReferenceIndex) -> CalcResult {
|
||||||
|
if args.len() != 2 {
|
||||||
|
return CalcResult::new_args_number_error(cell);
|
||||||
|
}
|
||||||
|
let value = match self.get_number(&args[0], cell) {
|
||||||
|
Ok(f) => f,
|
||||||
|
Err(s) => return s,
|
||||||
|
};
|
||||||
|
let significance = match self.get_number(&args[1], cell) {
|
||||||
|
Ok(f) => f,
|
||||||
|
Err(s) => return s,
|
||||||
|
};
|
||||||
|
if significance == 0.0 {
|
||||||
|
// This behaviour is different from FLOOR where division by zero returns an error
|
||||||
|
return CalcResult::Number(0.0);
|
||||||
|
}
|
||||||
|
if significance < 0.0 && value > 0.0 {
|
||||||
|
return CalcResult::Error {
|
||||||
|
error: Error::NUM,
|
||||||
|
origin: cell,
|
||||||
|
message: "Significance must be positive when value is positive".to_string(),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
let result = f64::ceil(value / significance) * significance;
|
||||||
|
CalcResult::Number(result)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn fn_ceiling_math(
|
||||||
|
&mut self,
|
||||||
|
args: &[Node],
|
||||||
|
cell: CellReferenceIndex,
|
||||||
|
) -> CalcResult {
|
||||||
|
let arg_count = args.len();
|
||||||
|
if arg_count > 3 {
|
||||||
|
return CalcResult::new_args_number_error(cell);
|
||||||
|
}
|
||||||
|
let value = match self.get_number(&args[0], cell) {
|
||||||
|
Ok(f) => f,
|
||||||
|
Err(s) => return s,
|
||||||
|
};
|
||||||
|
let significance = if arg_count > 1 {
|
||||||
|
match self.get_number(&args[1], cell) {
|
||||||
|
Ok(f) => f.abs(),
|
||||||
|
Err(s) => return s,
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
1.0
|
||||||
|
};
|
||||||
|
let mode = if arg_count > 2 {
|
||||||
|
match self.get_number(&args[2], cell) {
|
||||||
|
Ok(f) => f,
|
||||||
|
Err(s) => return s,
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
0.0
|
||||||
|
};
|
||||||
|
if significance == 0.0 {
|
||||||
|
return CalcResult::Number(0.0);
|
||||||
|
}
|
||||||
|
if value < 0.0 && mode != 0.0 {
|
||||||
|
let result = f64::floor(value / significance) * significance;
|
||||||
|
CalcResult::Number(result)
|
||||||
|
} else {
|
||||||
|
let result = f64::ceil(value / significance) * significance;
|
||||||
|
CalcResult::Number(result)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn fn_ceiling_precise(
|
||||||
|
&mut self,
|
||||||
|
args: &[Node],
|
||||||
|
cell: CellReferenceIndex,
|
||||||
|
) -> CalcResult {
|
||||||
|
let arg_count = args.len();
|
||||||
|
if arg_count > 2 {
|
||||||
|
return CalcResult::new_args_number_error(cell);
|
||||||
|
}
|
||||||
|
let value = match self.get_number(&args[0], cell) {
|
||||||
|
Ok(f) => f,
|
||||||
|
Err(s) => return s,
|
||||||
|
};
|
||||||
|
let significance = if arg_count > 1 {
|
||||||
|
match self.get_number(&args[1], cell) {
|
||||||
|
Ok(f) => f.abs(),
|
||||||
|
Err(s) => return s,
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
1.0
|
||||||
|
};
|
||||||
|
if significance == 0.0 {
|
||||||
|
return CalcResult::Number(0.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
let result = f64::ceil(value / significance) * significance;
|
||||||
|
CalcResult::Number(result)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn fn_iso_ceiling(&mut self, args: &[Node], cell: CellReferenceIndex) -> CalcResult {
|
||||||
|
// ISO.CEILING is equivalent to CEILING.PRECISE
|
||||||
|
self.fn_ceiling_precise(args, cell)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn fn_floor_math(&mut self, args: &[Node], cell: CellReferenceIndex) -> CalcResult {
|
||||||
|
let arg_count = args.len();
|
||||||
|
if arg_count > 3 {
|
||||||
|
return CalcResult::new_args_number_error(cell);
|
||||||
|
}
|
||||||
|
let value = match self.get_number(&args[0], cell) {
|
||||||
|
Ok(f) => f,
|
||||||
|
Err(s) => return s,
|
||||||
|
};
|
||||||
|
let significance = if arg_count > 1 {
|
||||||
|
match self.get_number(&args[1], cell) {
|
||||||
|
Ok(f) => f,
|
||||||
|
Err(s) => return s,
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
1.0
|
||||||
|
};
|
||||||
|
let mode = if arg_count > 2 {
|
||||||
|
match self.get_number(&args[2], cell) {
|
||||||
|
Ok(f) => f,
|
||||||
|
Err(s) => return s,
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
0.0
|
||||||
|
};
|
||||||
|
if significance == 0.0 {
|
||||||
|
return CalcResult::Number(0.0);
|
||||||
|
}
|
||||||
|
let significance = significance.abs();
|
||||||
|
if value < 0.0 && mode != 0.0 {
|
||||||
|
let result = f64::ceil(value / significance) * significance;
|
||||||
|
CalcResult::Number(result)
|
||||||
|
} else {
|
||||||
|
let result = f64::floor(value / significance) * significance;
|
||||||
|
CalcResult::Number(result)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn fn_floor_precise(
|
||||||
|
&mut self,
|
||||||
|
args: &[Node],
|
||||||
|
cell: CellReferenceIndex,
|
||||||
|
) -> CalcResult {
|
||||||
|
let arg_count = args.len();
|
||||||
|
if arg_count > 2 {
|
||||||
|
return CalcResult::new_args_number_error(cell);
|
||||||
|
}
|
||||||
|
let value = match self.get_number(&args[0], cell) {
|
||||||
|
Ok(f) => f,
|
||||||
|
Err(s) => return s,
|
||||||
|
};
|
||||||
|
let significance = if arg_count > 1 {
|
||||||
|
match self.get_number(&args[1], cell) {
|
||||||
|
Ok(f) => f.abs(),
|
||||||
|
Err(s) => return s,
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
1.0
|
||||||
|
};
|
||||||
|
if significance == 0.0 {
|
||||||
|
return CalcResult::Number(0.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
let result = f64::floor(value / significance) * significance;
|
||||||
|
CalcResult::Number(result)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn fn_mround(&mut self, args: &[Node], cell: CellReferenceIndex) -> CalcResult {
|
||||||
|
// MROUND(number, multiple)
|
||||||
|
if args.len() != 2 {
|
||||||
|
return CalcResult::new_args_number_error(cell);
|
||||||
|
}
|
||||||
|
let value = match self.get_number(&args[0], cell) {
|
||||||
|
Ok(f) => f,
|
||||||
|
Err(s) => return s,
|
||||||
|
};
|
||||||
|
let multiple = match self.get_number(&args[1], cell) {
|
||||||
|
Ok(f) => f,
|
||||||
|
Err(s) => return s,
|
||||||
|
};
|
||||||
|
if multiple == 0.0 {
|
||||||
|
return CalcResult::Number(0.0);
|
||||||
|
}
|
||||||
|
if (value > 0.0 && multiple < 0.0) || (value < 0.0 && multiple > 0.0) {
|
||||||
|
return CalcResult::Error {
|
||||||
|
error: Error::NUM,
|
||||||
|
origin: cell,
|
||||||
|
message: "number and multiple must have the same sign".to_string(),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
let result = (value / multiple).round() * multiple;
|
||||||
|
CalcResult::Number(result)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn fn_trunc(&mut self, args: &[Node], cell: CellReferenceIndex) -> CalcResult {
|
||||||
|
if args.len() > 2 {
|
||||||
|
return CalcResult::new_args_number_error(cell);
|
||||||
|
}
|
||||||
|
let value = match self.get_number(&args[0], cell) {
|
||||||
|
Ok(f) => f,
|
||||||
|
Err(s) => return s,
|
||||||
|
};
|
||||||
|
let num_digits = if args.len() == 2 {
|
||||||
|
match self.get_number(&args[1], cell) {
|
||||||
|
Ok(f) => {
|
||||||
|
if f > 0.0 {
|
||||||
|
f.floor()
|
||||||
|
} else {
|
||||||
|
f.ceil()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Err(s) => return s,
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
0.0
|
||||||
|
};
|
||||||
|
if !(-15.0..=15.0).contains(&num_digits) {
|
||||||
|
return CalcResult::Number(value);
|
||||||
|
}
|
||||||
|
CalcResult::Number(if value >= 0.0 {
|
||||||
|
f64::floor(value * 10f64.powf(num_digits)) / 10f64.powf(num_digits)
|
||||||
|
} else {
|
||||||
|
f64::ceil(value * 10f64.powf(num_digits)) / 10f64.powf(num_digits)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
single_number_fn!(fn_log10, |f| if f <= 0.0 {
|
single_number_fn!(fn_log10, |f| if f <= 0.0 {
|
||||||
Err(Error::NUM)
|
Err(Error::NUM)
|
||||||
} else {
|
} else {
|
||||||
@@ -487,6 +798,14 @@ impl Model {
|
|||||||
single_number_fn!(fn_sign, |f| Ok(f64::signum(f)));
|
single_number_fn!(fn_sign, |f| Ok(f64::signum(f)));
|
||||||
single_number_fn!(fn_degrees, |f| Ok(f * (180.0 / PI)));
|
single_number_fn!(fn_degrees, |f| Ok(f * (180.0 / PI)));
|
||||||
single_number_fn!(fn_radians, |f| Ok(f * (PI / 180.0)));
|
single_number_fn!(fn_radians, |f| Ok(f * (PI / 180.0)));
|
||||||
|
single_number_fn!(fn_odd, |f| {
|
||||||
|
let sign = f64::signum(f);
|
||||||
|
Ok(sign * (f64::ceil((f64::abs(f) - 1.0) / 2.0) * 2.0 + 1.0))
|
||||||
|
});
|
||||||
|
single_number_fn!(fn_even, |f| Ok(f64::signum(f)
|
||||||
|
* f64::ceil(f64::abs(f) / 2.0)
|
||||||
|
* 2.0));
|
||||||
|
single_number_fn!(fn_int, |f| Ok(f64::floor(f)));
|
||||||
|
|
||||||
pub(crate) fn fn_pi(&mut self, args: &[Node], cell: CellReferenceIndex) -> CalcResult {
|
pub(crate) fn fn_pi(&mut self, args: &[Node], cell: CellReferenceIndex) -> CalcResult {
|
||||||
if !args.is_empty() {
|
if !args.is_empty() {
|
||||||
|
|||||||
@@ -93,6 +93,21 @@ pub enum Function {
|
|||||||
Radians,
|
Radians,
|
||||||
Degrees,
|
Degrees,
|
||||||
|
|
||||||
|
Int,
|
||||||
|
Even,
|
||||||
|
Odd,
|
||||||
|
Ceiling,
|
||||||
|
CeilingMath,
|
||||||
|
CeilingPrecise,
|
||||||
|
Floor,
|
||||||
|
FloorMath,
|
||||||
|
FloorPrecise,
|
||||||
|
IsoCeiling,
|
||||||
|
Mod,
|
||||||
|
Quotient,
|
||||||
|
Mround,
|
||||||
|
Trunc,
|
||||||
|
|
||||||
// Information
|
// Information
|
||||||
ErrorType,
|
ErrorType,
|
||||||
Formulatext,
|
Formulatext,
|
||||||
@@ -286,7 +301,7 @@ pub enum Function {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Function {
|
impl Function {
|
||||||
pub fn into_iter() -> IntoIter<Function, 229> {
|
pub fn into_iter() -> IntoIter<Function, 243> {
|
||||||
[
|
[
|
||||||
Function::And,
|
Function::And,
|
||||||
Function::False,
|
Function::False,
|
||||||
@@ -332,6 +347,20 @@ impl Function {
|
|||||||
Function::Fact,
|
Function::Fact,
|
||||||
Function::Factdouble,
|
Function::Factdouble,
|
||||||
Function::Sign,
|
Function::Sign,
|
||||||
|
Function::Int,
|
||||||
|
Function::Even,
|
||||||
|
Function::Odd,
|
||||||
|
Function::Ceiling,
|
||||||
|
Function::CeilingMath,
|
||||||
|
Function::CeilingPrecise,
|
||||||
|
Function::Floor,
|
||||||
|
Function::FloorMath,
|
||||||
|
Function::FloorPrecise,
|
||||||
|
Function::IsoCeiling,
|
||||||
|
Function::Mod,
|
||||||
|
Function::Quotient,
|
||||||
|
Function::Mround,
|
||||||
|
Function::Trunc,
|
||||||
Function::Max,
|
Function::Max,
|
||||||
Function::Min,
|
Function::Min,
|
||||||
Function::Product,
|
Function::Product,
|
||||||
@@ -559,6 +588,14 @@ impl Function {
|
|||||||
Function::Sheet => "_xlfn.SHEET".to_string(),
|
Function::Sheet => "_xlfn.SHEET".to_string(),
|
||||||
Function::Formulatext => "_xlfn.FORMULATEXT".to_string(),
|
Function::Formulatext => "_xlfn.FORMULATEXT".to_string(),
|
||||||
Function::Isoweeknum => "_xlfn.ISOWEEKNUM".to_string(),
|
Function::Isoweeknum => "_xlfn.ISOWEEKNUM".to_string(),
|
||||||
|
|
||||||
|
Function::Ceiling => "_xlfn.CEILING".to_string(),
|
||||||
|
Function::CeilingMath => "_xlfn.CEILING.MATH".to_string(),
|
||||||
|
Function::CeilingPrecise => "_xlfn.CEILING.PRECISE".to_string(),
|
||||||
|
Function::FloorMath => "_xlfn.FLOOR.MATH".to_string(),
|
||||||
|
Function::FloorPrecise => "_xlfn.FLOOR.PRECISE".to_string(),
|
||||||
|
Function::IsoCeiling => "_xlfn.ISO.CEILING".to_string(),
|
||||||
|
|
||||||
_ => self.to_string(),
|
_ => self.to_string(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -615,6 +652,21 @@ impl Function {
|
|||||||
"RADIANS" => Some(Function::Radians),
|
"RADIANS" => Some(Function::Radians),
|
||||||
"DEGREES" => Some(Function::Degrees),
|
"DEGREES" => Some(Function::Degrees),
|
||||||
|
|
||||||
|
"INT" => Some(Function::Int),
|
||||||
|
"EVEN" => Some(Function::Even),
|
||||||
|
"ODD" => Some(Function::Odd),
|
||||||
|
"CEILING" | "_XLFN.CEILING" => Some(Function::Ceiling),
|
||||||
|
"CEILING.MATH" | "_XLFN.CEILING.MATH" => Some(Function::CeilingMath),
|
||||||
|
"CEILING.PRECISE" | "_XLFN.CEILING.PRECISE" => Some(Function::CeilingPrecise),
|
||||||
|
"FLOOR" => Some(Function::Floor),
|
||||||
|
"FLOOR.MATH" | "_XLFN.FLOOR.MATH" => Some(Function::FloorMath),
|
||||||
|
"FLOOR.PRECISE" | "_XLFN.FLOOR.PRECISE" => Some(Function::FloorPrecise),
|
||||||
|
"ISO.CEILING" | "_XLFN.ISO.CEILING" => Some(Function::IsoCeiling),
|
||||||
|
"MOD" => Some(Function::Mod),
|
||||||
|
"QUOTIENT" => Some(Function::Quotient),
|
||||||
|
"MROUND" => Some(Function::Mround),
|
||||||
|
"TRUNC" => Some(Function::Trunc),
|
||||||
|
|
||||||
"PI" => Some(Function::Pi),
|
"PI" => Some(Function::Pi),
|
||||||
"ABS" => Some(Function::Abs),
|
"ABS" => Some(Function::Abs),
|
||||||
"SQRT" => Some(Function::Sqrt),
|
"SQRT" => Some(Function::Sqrt),
|
||||||
@@ -824,6 +876,7 @@ impl Function {
|
|||||||
"GESTEP" => Some(Function::Gestep),
|
"GESTEP" => Some(Function::Gestep),
|
||||||
|
|
||||||
"SUBTOTAL" => Some(Function::Subtotal),
|
"SUBTOTAL" => Some(Function::Subtotal),
|
||||||
|
|
||||||
_ => None,
|
_ => None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1061,6 +1114,20 @@ impl fmt::Display for Function {
|
|||||||
Function::Sign => write!(f, "SIGN"),
|
Function::Sign => write!(f, "SIGN"),
|
||||||
Function::Radians => write!(f, "RADIANS"),
|
Function::Radians => write!(f, "RADIANS"),
|
||||||
Function::Degrees => write!(f, "DEGREES"),
|
Function::Degrees => write!(f, "DEGREES"),
|
||||||
|
Function::Int => write!(f, "INT"),
|
||||||
|
Function::Even => write!(f, "EVEN"),
|
||||||
|
Function::Odd => write!(f, "ODD"),
|
||||||
|
Function::Ceiling => write!(f, "CEILING"),
|
||||||
|
Function::CeilingMath => write!(f, "CEILING.MATH"),
|
||||||
|
Function::CeilingPrecise => write!(f, "CEILING.PRECISE"),
|
||||||
|
Function::Floor => write!(f, "FLOOR"),
|
||||||
|
Function::FloorMath => write!(f, "FLOOR.MATH"),
|
||||||
|
Function::FloorPrecise => write!(f, "FLOOR.PRECISE"),
|
||||||
|
Function::IsoCeiling => write!(f, "ISO.CEILING"),
|
||||||
|
Function::Mod => write!(f, "MOD"),
|
||||||
|
Function::Quotient => write!(f, "QUOTIENT"),
|
||||||
|
Function::Mround => write!(f, "MROUND"),
|
||||||
|
Function::Trunc => write!(f, "TRUNC"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1318,6 +1385,20 @@ impl Model {
|
|||||||
Function::Sign => self.fn_sign(args, cell),
|
Function::Sign => self.fn_sign(args, cell),
|
||||||
Function::Radians => self.fn_radians(args, cell),
|
Function::Radians => self.fn_radians(args, cell),
|
||||||
Function::Degrees => self.fn_degrees(args, cell),
|
Function::Degrees => self.fn_degrees(args, cell),
|
||||||
|
Function::Int => self.fn_int(args, cell),
|
||||||
|
Function::Even => self.fn_even(args, cell),
|
||||||
|
Function::Odd => self.fn_odd(args, cell),
|
||||||
|
Function::Ceiling => self.fn_ceiling(args, cell),
|
||||||
|
Function::CeilingMath => self.fn_ceiling_math(args, cell),
|
||||||
|
Function::CeilingPrecise => self.fn_ceiling_precise(args, cell),
|
||||||
|
Function::Floor => self.fn_floor(args, cell),
|
||||||
|
Function::FloorMath => self.fn_floor_math(args, cell),
|
||||||
|
Function::FloorPrecise => self.fn_floor_precise(args, cell),
|
||||||
|
Function::IsoCeiling => self.fn_iso_ceiling(args, cell),
|
||||||
|
Function::Mod => self.fn_mod(args, cell),
|
||||||
|
Function::Quotient => self.fn_quotient(args, cell),
|
||||||
|
Function::Mround => self.fn_mround(args, cell),
|
||||||
|
Function::Trunc => self.fn_trunc(args, cell),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Binary file not shown.
BIN
xlsx/tests/calc_tests/RADIANS_DEGREES_and_mathematical.xlsx
Normal file
BIN
xlsx/tests/calc_tests/RADIANS_DEGREES_and_mathematical.xlsx
Normal file
Binary file not shown.
Reference in New Issue
Block a user