use uninum::{Number, num};
fn celsius_to_fahrenheit(celsius: Number) -> Number {
&celsius * num!(9) / num!(5) + num!(32)
}
fn fahrenheit_to_celsius(fahrenheit: Number) -> Number {
(&fahrenheit - num!(32)) * num!(5) / num!(9)
}
fn celsius_to_kelvin(celsius: Number) -> Number {
celsius + num!(273.15)
}
fn run_temperature_conversions() {
let c = num!(25.0);
let f = celsius_to_fahrenheit(c.clone());
assert!(f.approx_eq(&num!(77.0), 1e-10, 0.0));
let c2 = fahrenheit_to_celsius(num!(32.0));
assert!(c2.approx_eq(&num!(0.0), 1e-10, 0.0));
let k = celsius_to_kelvin(num!(0.0));
assert!(k.approx_eq(&num!(273.15), 1e-10, 0.0));
println!("Temperature conversions: 25°C -> {f}°F, 0°C -> {k} K");
}
fn dot_product(a: &[Number], b: &[Number]) -> Number {
assert_eq!(a.len(), b.len(), "Vectors must have same length");
a.iter()
.zip(b.iter())
.map(|(x, y)| x.clone() * y.clone())
.reduce(|acc, x| acc + x)
.unwrap_or_else(|| num!(0))
}
fn vector_magnitude(v: &[Number]) -> Number {
let sum_of_squares = v
.iter()
.map(|x| x.clone() * x.clone())
.reduce(|acc, x| acc + x)
.unwrap_or_else(|| num!(0));
sum_of_squares.sqrt()
}
fn run_vector_operations() {
let v1 = vec![num!(1), num!(2), num!(3)];
let v2 = vec![num!(4.0), num!(5.0), num!(6.0)];
let result = dot_product(&v1, &v2);
assert!(result.approx_eq(&num!(32.0), 1e-10, 0.0));
let magnitude = vector_magnitude(&v1);
let expected_magnitude = num!(14.0_f64.sqrt());
assert!(magnitude.approx_eq(&expected_magnitude, 1e-10, 0.0));
println!("Vector operations: dot={result}, |v1|≈{magnitude}");
}
fn kinetic_energy(mass: Number, velocity: Number) -> Number {
num!(0.5) * &mass * velocity.pow(&num!(2))
}
fn potential_energy(mass: Number, height: Number) -> Number {
let gravity = num!(9.81);
&mass * &gravity * &height
}
fn force(mass: Number, acceleration: Number) -> Number {
mass * acceleration
}
fn run_physics_calculations() {
let mass = num!(10.0);
let velocity = num!(5.0);
let height = num!(2.0);
let acceleration = num!(2.0);
let ke = kinetic_energy(mass.clone(), velocity);
let pe = potential_energy(mass.clone(), height);
let f = force(mass, acceleration);
assert!(ke.approx_eq(&num!(125.0), 1e-10, 0.0));
assert!(pe.approx_eq(&num!(196.2), 1e-10, 0.0));
assert!(f.approx_eq(&num!(20.0), 1e-10, 0.0));
assert!(ke.is_finite() && pe.is_finite() && f.is_finite());
println!("Physics calculations: KE={ke}, PE={pe}, F={f}");
}
fn voltage(current: Number, resistance: Number) -> Number {
current * resistance
}
fn power(voltage: Number, current: Number) -> Number {
voltage * current
}
fn power_from_resistance(current: Number, resistance: Number) -> Number {
let voltage = voltage(current.clone(), resistance);
power(voltage, current)
}
fn run_electrical_calculations() {
let current = num!(2.0);
let resistance = num!(5.0);
let v = voltage(current.clone(), resistance.clone());
let p = power_from_resistance(current, resistance);
assert!(v.approx_eq(&num!(10.0), 1e-10, 0.0));
assert!(p.approx_eq(&num!(20.0), 1e-10, 0.0));
assert!(v.is_positive() && p.is_positive());
println!("Electrical calculations: voltage={v}, power={p}");
}
fn pressure_from_gas_law(volume: Number, moles: Number, temperature: Number) -> Number {
let gas_constant = num!(0.08314);
&moles * &gas_constant * &temperature / &volume
}
fn run_chemistry_calculations() {
let volume = num!(10.0);
let moles = num!(2.0);
let temperature = num!(298.15);
let pressure = pressure_from_gas_law(volume, moles, temperature);
let expected = num!(4.95782);
assert!(
pressure.approx_eq(&expected, 1e-10, 0.0),
"Ideal gas law calculation error"
);
println!("Chemistry calculation: pressure ≈ {pressure} bar");
}
fn main() {
run_temperature_conversions();
run_vector_operations();
run_physics_calculations();
run_electrical_calculations();
run_chemistry_calculations();
println!("Scientific examples completed successfully.");
}