pub mod math {
pub const PI: f64 = std::f64::consts::PI;
pub const E: f64 = std::f64::consts::E;
pub const EULER: f64 = 0.577_215_664_901_532_9;
pub const GOLDEN: f64 = 1.618_033_988_749_895;
pub const GOLDEN_RATIO: f64 = GOLDEN;
pub const SQRT2: f64 = std::f64::consts::SQRT_2;
pub const SQRTPI: f64 = 1.772_453_850_905_516;
pub const LN2: f64 = std::f64::consts::LN_2;
pub const LN10: f64 = std::f64::consts::LN_10;
}
pub mod physical {
pub const SPEED_OF_LIGHT: f64 = 299_792_458.0;
pub const C: f64 = SPEED_OF_LIGHT;
pub const MAGNETIC_CONSTANT: f64 = 1.25663706212e-6;
pub const MU_0: f64 = MAGNETIC_CONSTANT;
pub const ELECTRIC_CONSTANT: f64 = 8.8541878128e-12;
pub const EPSILON_0: f64 = ELECTRIC_CONSTANT;
pub const GRAVITATIONAL_CONSTANT: f64 = 6.67430e-11;
pub const G: f64 = GRAVITATIONAL_CONSTANT;
pub const STANDARD_GRAVITY: f64 = 9.80665;
pub const G_ACCEL: f64 = STANDARD_GRAVITY;
pub const PLANCK: f64 = 6.62607015e-34;
pub const H: f64 = PLANCK;
pub const REDUCED_PLANCK: f64 = 1.054571817e-34;
pub const HBAR: f64 = REDUCED_PLANCK;
pub const ELEMENTARY_CHARGE: f64 = 1.602176634e-19;
pub const E_CHARGE: f64 = ELEMENTARY_CHARGE;
pub const ELECTRON_MASS: f64 = 9.1093837015e-31;
pub const M_E: f64 = ELECTRON_MASS;
pub const PROTON_MASS: f64 = 1.67262192369e-27;
pub const M_P: f64 = PROTON_MASS;
pub const NEUTRON_MASS: f64 = 1.67492749804e-27;
pub const M_N: f64 = NEUTRON_MASS;
pub const ATOMIC_MASS: f64 = 1.66053906660e-27;
pub const M_U: f64 = ATOMIC_MASS;
pub const U: f64 = ATOMIC_MASS;
pub const FINE_STRUCTURE: f64 = 7.2973525693e-3;
pub const ALPHA: f64 = FINE_STRUCTURE;
pub const RYDBERG: f64 = 10973731.568160;
pub const AVOGADRO: f64 = 6.02214076e23;
pub const N_A: f64 = AVOGADRO;
pub const GAS_CONSTANT: f64 = 8.31446261815324;
pub const R: f64 = GAS_CONSTANT;
pub const BOLTZMANN: f64 = 1.380649e-23;
pub const K: f64 = BOLTZMANN;
pub const STEFAN_BOLTZMANN: f64 = 5.670374419e-8;
pub const SIGMA: f64 = STEFAN_BOLTZMANN;
pub const WIEN: f64 = 2.897771955e-3;
pub const ELECTRON_VOLT: f64 = 1.602176634e-19;
pub const EV: f64 = ELECTRON_VOLT;
pub const ASTRONOMICAL_UNIT: f64 = 1.495978707e11;
pub const AU: f64 = ASTRONOMICAL_UNIT;
pub const LIGHT_YEAR: f64 = 9.4607304725808e15;
pub const PARSEC: f64 = 3.085_677_581_491_367e16;
}
pub mod prefixes {
pub mod si {
pub const QUETTA: f64 = 1e30;
pub const RONNA: f64 = 1e27;
pub const YOTTA: f64 = 1e24;
pub const ZETTA: f64 = 1e21;
pub const EXA: f64 = 1e18;
pub const PETA: f64 = 1e15;
pub const TERA: f64 = 1e12;
pub const GIGA: f64 = 1e9;
pub const MEGA: f64 = 1e6;
pub const KILO: f64 = 1e3;
pub const HECTO: f64 = 1e2;
pub const DEKA: f64 = 1e1;
pub const DECI: f64 = 1e-1;
pub const CENTI: f64 = 1e-2;
pub const MILLI: f64 = 1e-3;
pub const MICRO: f64 = 1e-6;
pub const NANO: f64 = 1e-9;
pub const PICO: f64 = 1e-12;
pub const FEMTO: f64 = 1e-15;
pub const ATTO: f64 = 1e-18;
pub const ZEPTO: f64 = 1e-21;
pub const YOCTO: f64 = 1e-24;
pub const RONTO: f64 = 1e-27;
pub const QUECTO: f64 = 1e-30;
}
pub use si::*;
pub mod binary {
pub const KIBI: f64 = 1024.0;
pub const MEBI: f64 = 1_048_576.0;
pub const GIBI: f64 = 1_073_741_824.0;
pub const TEBI: f64 = 1_099_511_627_776.0;
pub const PEBI: f64 = 1_125_899_906_842_624.0;
pub const EXBI: f64 = 1_152_921_504_606_846_976.0;
pub const ZEBI: f64 = 1_180_591_620_717_411_303_424.0;
pub const YOBI: f64 = 1_208_925_819_614_629_174_706_176.0;
}
pub use binary::*;
}
pub mod conversions {
pub mod angle {
use crate::constants::math::PI;
pub const DEG_TO_RAD: f64 = PI / 180.0;
pub const RAD_TO_DEG: f64 = 180.0 / PI;
pub const DEGREE: f64 = DEG_TO_RAD;
pub const ARCMIN: f64 = DEGREE / 60.0;
pub const ARCMINUTE: f64 = ARCMIN;
pub const ARCSEC: f64 = ARCMIN / 60.0;
pub const ARCSECOND: f64 = ARCSEC;
}
pub use angle::*;
pub mod time {
pub const MINUTE: f64 = 60.0;
pub const HOUR: f64 = 60.0 * MINUTE;
pub const DAY: f64 = 24.0 * HOUR;
pub const WEEK: f64 = 7.0 * DAY;
pub const YEAR: f64 = 365.0 * DAY;
pub const JULIAN_YEAR: f64 = 365.25 * DAY;
}
pub use time::*;
pub mod length {
pub const METER: f64 = 1.0;
pub const INCH: f64 = 0.0254;
pub const FOOT: f64 = 12.0 * INCH;
pub const YARD: f64 = 3.0 * FOOT;
pub const MILE: f64 = 1760.0 * YARD;
pub const MIL: f64 = INCH / 1000.0;
pub const POINT: f64 = INCH / 72.0;
pub const PT: f64 = POINT;
pub const SURVEY_FOOT: f64 = 1200.0 / 3937.0;
pub const SURVEY_MILE: f64 = 5280.0 * SURVEY_FOOT;
pub const NAUTICAL_MILE: f64 = 1852.0;
pub const FERMI: f64 = 1e-15;
pub const ANGSTROM: f64 = 1e-10;
pub const MICRON: f64 = 1e-6;
pub const INCH_TO_METER: f64 = INCH;
pub const FOOT_TO_METER: f64 = FOOT;
pub const YARD_TO_METER: f64 = YARD;
pub const MILE_TO_METER: f64 = MILE;
}
pub use length::*;
pub mod mass {
pub const GRAM: f64 = 1e-3;
pub const METRIC_TON: f64 = 1e3;
pub const GRAIN: f64 = 64.79891e-6;
pub const POUND: f64 = 7000.0 * GRAIN;
pub const LB: f64 = POUND;
pub const BLOB: f64 = POUND * 9.80665 / 0.0254;
pub const SLINCH: f64 = BLOB;
pub const SLUG: f64 = BLOB / 12.0;
pub const OUNCE: f64 = POUND / 16.0;
pub const OZ: f64 = OUNCE;
pub const STONE: f64 = 14.0 * POUND;
pub const LONG_TON: f64 = 2240.0 * POUND;
pub const SHORT_TON: f64 = 2000.0 * POUND;
pub const TROY_OUNCE: f64 = 480.0 * GRAIN;
pub const TROY_POUND: f64 = 12.0 * TROY_OUNCE;
pub const CARAT: f64 = 200e-6;
pub const POUND_TO_KG: f64 = POUND;
}
pub use mass::*;
pub mod pressure {
pub const ATMOSPHERE: f64 = 101325.0;
pub const ATM: f64 = ATMOSPHERE;
pub const BAR: f64 = 1e5;
pub const TORR: f64 = ATMOSPHERE / 760.0;
pub const MMHG: f64 = TORR;
pub const PSI: f64 = POUND_FORCE / (INCH * INCH);
use super::force::POUND_FORCE;
use super::length::INCH;
}
pub use pressure::*;
pub mod area {
use super::length::FOOT;
pub const HECTARE: f64 = 1e4;
pub const ACRE: f64 = 43560.0 * FOOT * FOOT;
}
pub use area::*;
pub mod volume {
use super::length::INCH;
pub const LITER: f64 = 1e-3;
pub const LITRE: f64 = LITER;
pub const GALLON_US: f64 = 231.0 * INCH * INCH * INCH;
pub const GALLON: f64 = GALLON_US;
pub const GALLON_IMP: f64 = 4.54609e-3;
pub const FLUID_OUNCE_US: f64 = GALLON_US / 128.0;
pub const FLUID_OUNCE: f64 = FLUID_OUNCE_US;
pub const FLUID_OUNCE_IMP: f64 = GALLON_IMP / 160.0;
pub const BARREL: f64 = 42.0 * GALLON_US;
pub const BBL: f64 = BARREL;
pub const GALLON_TO_CUBIC_METER: f64 = GALLON_US;
}
pub use volume::*;
pub mod speed {
use super::length::{MILE, NAUTICAL_MILE};
use super::time::HOUR;
pub const KMH: f64 = 1e3 / 3600.0;
pub const MPH: f64 = MILE / HOUR;
pub const MACH: f64 = 340.5;
pub const SPEED_OF_SOUND: f64 = MACH;
pub const KNOT: f64 = NAUTICAL_MILE / HOUR;
}
pub use speed::*;
pub mod temperature {
pub const ZERO_CELSIUS: f64 = 273.15;
pub const DEGREE_FAHRENHEIT: f64 = 1.0 / 1.8;
pub fn convert_temperature(value: f64, from_scale: &str, to_scale: &str) -> f64 {
let kelvin = match from_scale.to_lowercase().as_str() {
"celsius" | "c" => value + ZERO_CELSIUS,
"kelvin" | "k" => value,
"fahrenheit" | "f" => (value - 32.0) * 5.0 / 9.0 + ZERO_CELSIUS,
"rankine" | "r" => value * 5.0 / 9.0,
_ => panic!("Unsupported 'from' scale: {}. Supported scales are Celsius, Kelvin, Fahrenheit, and Rankine", from_scale),
};
match to_scale.to_lowercase().as_str() {
"celsius" | "c" => kelvin - ZERO_CELSIUS,
"kelvin" | "k" => kelvin,
"fahrenheit" | "f" => (kelvin - ZERO_CELSIUS) * 9.0 / 5.0 + 32.0,
"rankine" | "r" => kelvin * 9.0 / 5.0,
_ => panic!("Unsupported 'to' scale: {}. Supported scales are Celsius, Kelvin, Fahrenheit, and Rankine", to_scale),
}
}
}
pub use temperature::*;
pub mod energy {
use super::mass::POUND;
use super::temperature::DEGREE_FAHRENHEIT;
use crate::constants::physical::ELEMENTARY_CHARGE;
pub const ELECTRON_VOLT: f64 = ELEMENTARY_CHARGE;
pub const EV: f64 = ELECTRON_VOLT;
pub const CALORIE_TH: f64 = 4.184;
pub const CALORIE: f64 = CALORIE_TH;
pub const CALORIE_IT: f64 = 4.1868;
pub const ERG: f64 = 1e-7;
pub const BTU_IT: f64 = POUND * DEGREE_FAHRENHEIT * CALORIE_IT / 1e-3;
pub const BTU: f64 = BTU_IT;
pub const BTU_TH: f64 = POUND * DEGREE_FAHRENHEIT * CALORIE_TH / 1e-3;
pub const TON_TNT: f64 = 1e9 * CALORIE_TH;
}
pub use energy::*;
pub mod power {
use super::length::FOOT;
use super::mass::POUND;
const STANDARD_GRAVITY: f64 = 9.80665;
pub const HORSEPOWER: f64 = 550.0 * FOOT * POUND * STANDARD_GRAVITY;
pub const HP: f64 = HORSEPOWER;
}
pub use power::*;
pub mod force {
use super::mass::POUND;
const STANDARD_GRAVITY: f64 = 9.80665;
pub const DYNE: f64 = 1e-5;
pub const DYN: f64 = DYNE;
pub const POUND_FORCE: f64 = POUND * STANDARD_GRAVITY;
pub const LBF: f64 = POUND_FORCE;
pub const KILOGRAM_FORCE: f64 = STANDARD_GRAVITY;
pub const KGF: f64 = KILOGRAM_FORCE;
}
pub use force::*;
pub mod optics {
use crate::constants::physical::SPEED_OF_LIGHT;
pub fn lambda2nu(wavelength: f64) -> f64 {
SPEED_OF_LIGHT / wavelength
}
pub fn nu2lambda(frequency: f64) -> f64 {
SPEED_OF_LIGHT / frequency
}
}
pub use optics::*;
}
pub use self::physical::*;
pub use self::math::*;
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_mathematical_constants() {
assert_eq!(math::PI, std::f64::consts::PI);
assert_eq!(math::E, std::f64::consts::E);
assert!((math::GOLDEN - 1.618033988749895).abs() < 1e-14);
}
#[test]
fn test_physical_constants() {
assert_eq!(physical::SPEED_OF_LIGHT, 299_792_458.0);
assert_eq!(physical::C, physical::SPEED_OF_LIGHT);
assert_eq!(physical::ELECTRON_VOLT, 1.602176634e-19);
}
#[test]
fn test_unit_conversions() {
assert!((conversions::MILE_TO_METER - 1609.344).abs() < 1e-10);
assert_eq!(conversions::INCH, 0.0254);
assert_eq!(conversions::METER, 1.0);
}
#[test]
fn test_temperature_conversion() {
let celsius = 100.0;
let kelvin = conversions::temperature::convert_temperature(celsius, "celsius", "kelvin");
assert!((kelvin - 373.15).abs() < 1e-10);
let fahrenheit =
conversions::temperature::convert_temperature(celsius, "celsius", "fahrenheit");
assert!((fahrenheit - 212.0).abs() < 1e-10);
let back_to_celsius =
conversions::temperature::convert_temperature(fahrenheit, "fahrenheit", "celsius");
assert!((back_to_celsius - celsius).abs() < 1e-10);
}
#[test]
fn test_prefix_values() {
assert_eq!(prefixes::KILO, 1e3);
assert_eq!(prefixes::MEGA, 1e6);
assert_eq!(prefixes::MICRO, 1e-6);
assert_eq!(prefixes::KIBI, 1024.0);
assert_eq!(prefixes::MEBI, 1024.0 * 1024.0);
}
#[test]
fn test_optics_conversions() {
let wavelength = 1.0; let frequency = conversions::optics::lambda2nu(wavelength);
assert!((frequency - physical::SPEED_OF_LIGHT).abs() < 1e-10);
let back_to_wavelength = conversions::optics::nu2lambda(frequency);
assert!((back_to_wavelength - wavelength).abs() < 1e-10);
}
}