Imports name this capability’s declared dependencies, which fune builds next to it in your project; each one links to its page.
use super::funejson::Value; ← the fune runtime: the JSON value the test vectors use; fune build keeps it only where a signature takes one
const MAX_SAFE: i64 = 9_007_199_254_740_991;
fn check_safe(name: &str, value: i64) {
// i64 could go further, but TypeScript cannot, and the three languages
// must give the same answer or the same error.
if !(-MAX_SAFE..=MAX_SAFE).contains(&value) {
panic!("{} is outside the safe integer range (±9007199254740991)", name);
}
}
/// Euclid's algorithm on wide integers. Never negative; `gcd_wide(0, 0)` is 0.
/// Exported for fraction arithmetic (math.rational), which reduces products
/// that are already past 2^53 before it checks them.
pub fn gcd_wide(a: i128, b: i128) -> i128 {
let mut x = a.abs();
let mut y = b.abs();
while y != 0 {
let r = x % y;
x = y;
y = r;
}
x
}
/// Greatest common divisor, never negative; `gcd(0, n)` is `|n|` and
/// `gcd(0, 0)` is 0.
///
/// # Panics
/// Panics if either input is outside ±(2^53 - 1).
pub fn gcd(a: i64, b: i64) -> i64 {
check_safe("a", a);
check_safe("b", b);
gcd_wide(a as i128, b as i128) as i64
}
// Refuse what the typed signature cannot hold, with the wording TypeScript
// and Python use, rather than let the conversion quietly truncate it.
fn int_arg(v: &Value, name: &str) -> i64 {
if let Value::Float(f) = v {
if f.fract() != 0.0 {
panic!("{} must be an integer, received {}", name, f);
}
}
v.as_i64()
}
pub fn fune_vector(args: &[Value]) -> Value {
Value::Int(gcd(int_arg(&args[0], "a"), int_arg(&args[1], "b")))
}