From 7892eee23ea915bec4ff85b6d9a5854a14541e18 Mon Sep 17 00:00:00 2001 From: PaddiM8 Date: Sat, 1 Jan 2022 00:58:20 +0100 Subject: [PATCH] Bitshift operations, closes #80 --- kalk/src/prelude/mod.rs | 5 +++++ kalk/src/prelude/regular.rs | 26 ++++++++++++++++++++++++++ kalk/src/prelude/with_rug.rs | 35 +++++++++++++++++++++++++++++++++++ 3 files changed, 66 insertions(+) diff --git a/kalk/src/prelude/mod.rs b/kalk/src/prelude/mod.rs index b36b46e..00379ee 100644 --- a/kalk/src/prelude/mod.rs +++ b/kalk/src/prelude/mod.rs @@ -91,10 +91,15 @@ lazy_static! { m.insert("sqrt", (UnaryFuncInfo(sqrt, Other), "")); m.insert("√", (UnaryFuncInfo(sqrt, Other), "")); m.insert("trunc", (UnaryFuncInfo(trunc, Other), "")); + m.insert("bitcmp", (UnaryFuncInfo(bitcmp, Other), "")); m }; pub static ref BINARY_FUNCS: HashMap<&'static str, (BinaryFuncInfo, &'static str)> = { let mut m = HashMap::new(); + m.insert("bitand", (BinaryFuncInfo(bitand, Other), "")); + m.insert("bitor", (BinaryFuncInfo(bitor, Other), "")); + m.insert("bitxor", (BinaryFuncInfo(bitxor, Other), "")); + m.insert("bitshift", (BinaryFuncInfo(bitshift, Other), "")); m.insert("max", (BinaryFuncInfo(max, Other), "")); m.insert("min", (BinaryFuncInfo(min, Other), "")); m.insert("hypot", (BinaryFuncInfo(hypot, Other), "")); diff --git a/kalk/src/prelude/regular.rs b/kalk/src/prelude/regular.rs index 41bbe5a..5adb16a 100644 --- a/kalk/src/prelude/regular.rs +++ b/kalk/src/prelude/regular.rs @@ -50,6 +50,32 @@ pub(crate) mod funcs { 2f64.sqrt() * pi.sqrt() * t.powf(x - 0.5f64) * (-t).exp() * a } + pub fn bitcmp(x: KalkNum, y: KalkNum) -> KalkNum { + KalkNum::from(!x.value.round() as i32) + } + + pub fn bitand(x: KalkNum, y: KalkNum) -> KalkNum { + KalkNum::from(x.value.round() as i32 & y.value.round() as i32) + } + + pub fn bitor(x: KalkNum, y: KalkNum) -> KalkNum { + KalkNum::from(x.value.round() as i32 | y.value.round() as i32) + } + + pub fn bitxor(x: KalkNum, y: KalkNum) -> KalkNum { + KalkNum::from(x.value.round() as i32 ^ y.value.round() as i32) + } + + pub fn bitshift(x: KalkNum, y: KalkNum) -> KalkNum { + let x = x.value.round() as i32; + let y = y.value.round() as i32; + if y < 0 { + KalkNum::from((x >> y.abs())) + } else { + KalkNum::from((x << y)) + } + } + pub fn hypot(x: KalkNum, y: KalkNum) -> KalkNum { if x.has_imaginary() || y.has_imaginary() { let abs_x = abs(x); diff --git a/kalk/src/prelude/with_rug.rs b/kalk/src/prelude/with_rug.rs index 4a2f3ab..acf36d0 100644 --- a/kalk/src/prelude/with_rug.rs +++ b/kalk/src/prelude/with_rug.rs @@ -18,6 +18,41 @@ pub(crate) mod funcs { KalkNum::new(x.value.gamma(), &x.unit) } + pub fn bitcmp(x: KalkNum) -> KalkNum { + KalkNum::from(!x.value.to_i32_saturating().unwrap_or(i32::MAX)) + } + + pub fn bitand(x: KalkNum, y: KalkNum) -> KalkNum { + KalkNum::from( + x.value.to_i32_saturating().unwrap_or(i32::MAX) + & y.value.to_i32_saturating().unwrap_or(i32::MAX), + ) + } + + pub fn bitor(x: KalkNum, y: KalkNum) -> KalkNum { + KalkNum::from( + x.value.to_i32_saturating().unwrap_or(i32::MAX) + | y.value.to_i32_saturating().unwrap_or(i32::MAX), + ) + } + + pub fn bitxor(x: KalkNum, y: KalkNum) -> KalkNum { + KalkNum::from( + x.value.to_i32_saturating().unwrap_or(i32::MAX) + ^ y.value.to_i32_saturating().unwrap_or(i32::MAX), + ) + } + + pub fn bitshift(x: KalkNum, y: KalkNum) -> KalkNum { + let x = x.value.to_i32_saturating().unwrap_or(i32::MAX) as i32; + let y = y.value.to_i32_saturating().unwrap_or(i32::MAX) as i32; + if y < 0 { + KalkNum::from(x >> y.abs()) + } else { + KalkNum::from(x << y) + } + } + pub fn hypot(x: KalkNum, y: KalkNum) -> KalkNum { if x.has_imaginary() || y.has_imaginary() { let abs_x = abs(x);