1use std::f64;23use jrsonnet_evaluator::{function::builtin, typed::PositiveF64};45#[builtin]6pub fn builtin_abs(n: f64) -> f64 {7 n.abs()8}910#[builtin]11pub fn builtin_sign(n: f64) -> f64 {12 if n == 0. { 0. } else { n.signum() }13}1415#[builtin]16pub fn builtin_max(a: f64, b: f64) -> f64 {17 a.max(b)18}1920#[builtin]21pub fn builtin_min(a: f64, b: f64) -> f64 {22 a.min(b)23}2425#[allow(non_snake_case)]26#[builtin]27pub fn builtin_clamp(x: f64, minVal: f64, maxVal: f64) -> f64 {28 x.clamp(minVal, maxVal)29}3031#[builtin]32pub fn builtin_sum(arr: Vec<f64>) -> f64 {33 arr.iter().sum()34}3536#[builtin]37pub fn builtin_modulo(x: f64, y: f64) -> f64 {38 x % y39}4041#[builtin]42pub fn builtin_floor(x: f64) -> f64 {43 x.floor()44}4546#[builtin]47pub fn builtin_ceil(x: f64) -> f64 {48 x.ceil()49}5051#[builtin]52pub fn builtin_log(x: f64) -> f64 {53 x.ln()54}5556#[builtin]57pub fn builtin_log2(x: f64) -> f64 {58 x.log2()59}6061#[builtin]62pub fn builtin_log10(x: f64) -> f64 {63 x.log10()64}6566#[builtin]67pub fn builtin_pow(x: f64, n: f64) -> f64 {68 x.powf(n)69}7071#[builtin]72pub fn builtin_sqrt(x: PositiveF64) -> f64 {73 x.0.sqrt()74}7576#[builtin]77pub fn builtin_sin(x: f64) -> f64 {78 x.sin()79}8081#[builtin]82pub fn builtin_cos(x: f64) -> f64 {83 x.cos()84}8586#[builtin]87pub fn builtin_tan(x: f64) -> f64 {88 x.tan()89}9091#[builtin]92pub fn builtin_asin(x: f64) -> f64 {93 x.asin()94}9596#[builtin]97pub fn builtin_acos(x: f64) -> f64 {98 x.acos()99}100101#[builtin]102pub fn builtin_atan(x: f64) -> f64 {103 x.atan()104}105106#[builtin]107pub fn builtin_atan2(y: f64, x: f64) -> f64 {108 y.atan2(x)109}110111#[builtin]112pub fn builtin_exp(x: f64) -> f64 {113 x.exp()114}115116fn frexp(s: f64) -> (f64, i16) {117 if s == 0.0 {118 (s, 0)119 } else {120 let lg = s.abs().log2();121 let x = (lg - lg.floor() - 1.0).exp2();122 let exp = lg.floor() + 1.0;123 #[expect(clippy::cast_possible_truncation, reason = "exponent can fit in i16")]124 (s.signum() * x, exp as i16)125 }126}127128#[builtin]129pub fn builtin_mantissa(x: f64) -> f64 {130 frexp(x).0131}132133#[builtin]134pub fn builtin_exponent(x: f64) -> i16 {135 frexp(x).1136}137138#[builtin]139pub fn builtin_round(x: f64) -> f64 {140 x.round()141}142143#[builtin]144pub fn builtin_is_even(x: f64) -> bool {145 builtin_round(x) % 2.0 == 0.0146}147148#[builtin]149#[allow(clippy::float_cmp)]150pub fn builtin_is_odd(x: f64) -> bool {151 builtin_round(x) % 2.0 == 1.0152}153154#[builtin]155#[allow(clippy::float_cmp)]156pub fn builtin_is_integer(x: f64) -> bool {157 builtin_round(x) == x158}159160#[builtin]161#[allow(clippy::float_cmp)]162pub fn builtin_is_decimal(x: f64) -> bool {163 builtin_round(x) != x164}165166#[builtin]167pub fn builtin_deg2rad(x: f64) -> f64 {168 x.to_radians()169}170171#[builtin]172pub fn builtin_rad2deg(x: f64) -> f64 {173 x.to_degrees()174}175176#[builtin]177pub fn builtin_hypot(x: f64, y: f64) -> f64 {178 x.hypot(y)179}