From af44aa6d4187a14d3282ad5c69ea5c920c72da35 Mon Sep 17 00:00:00 2001 From: Ali Alimohammadi Date: Mon, 19 Jan 2026 19:07:04 -0800 Subject: [PATCH 1/5] feat: add comprehensive temperature conversion functions --- DIRECTORY.md | 1 + src/conversions/mod.rs | 17 ++ src/conversions/temperature.rs | 431 +++++++++++++++++++++++++++++++++ 3 files changed, 449 insertions(+) create mode 100644 src/conversions/temperature.rs diff --git a/DIRECTORY.md b/DIRECTORY.md index ac27b183e8f..ec5f808a09b 100644 --- a/DIRECTORY.md +++ b/DIRECTORY.md @@ -87,6 +87,7 @@ * [RGB-HSV Conversion](https://github.com/TheAlgorithms/Rust/blob/master/src/conversions/rgb_hsv_conversion.rs) * [Roman Numerals](https://github.com/TheAlgorithms/Rust/blob/master/src/conversions/roman_numerals.rs) * [Time Units](https://github.com/TheAlgorithms/Rust/blob/master/src/conversions/time_units.rs) + * [Temperature](https://github.com/TheAlgorithms/Rust/blob/master/src/conversions/temperature.rs) * Data Structures * [AVL Tree](https://github.com/TheAlgorithms/Rust/blob/master/src/data_structures/avl_tree.rs) * [B-Tree](https://github.com/TheAlgorithms/Rust/blob/master/src/data_structures/b_tree.rs) diff --git a/src/conversions/mod.rs b/src/conversions/mod.rs index 6f7b9955f23..54473ea398b 100644 --- a/src/conversions/mod.rs +++ b/src/conversions/mod.rs @@ -16,6 +16,7 @@ mod order_of_magnitude_conversion; mod rgb_cmyk_conversion; mod rgb_hsv_conversion; mod roman_numerals; +mod temperature; mod time_units; pub use self::binary_to_decimal::binary_to_decimal; @@ -38,4 +39,20 @@ pub use self::order_of_magnitude_conversion::{ pub use self::rgb_cmyk_conversion::rgb_to_cmyk; pub use self::rgb_hsv_conversion::{hsv_to_rgb, rgb_to_hsv, ColorError, Hsv, Rgb}; pub use self::roman_numerals::{int_to_roman, roman_to_int}; +pub use self::temperature::{ + celsius_to_delisle, celsius_to_fahrenheit, celsius_to_kelvin, celsius_to_newton, + celsius_to_rankine, celsius_to_reaumur, celsius_to_romer, delisle_to_celsius, + delisle_to_fahrenheit, delisle_to_kelvin, delisle_to_newton, delisle_to_rankine, + delisle_to_reaumur, delisle_to_romer, fahrenheit_to_celsius, fahrenheit_to_delisle, + fahrenheit_to_kelvin, fahrenheit_to_newton, fahrenheit_to_rankine, fahrenheit_to_reaumur, + fahrenheit_to_romer, kelvin_to_celsius, kelvin_to_delisle, kelvin_to_fahrenheit, + kelvin_to_newton, kelvin_to_rankine, kelvin_to_reaumur, kelvin_to_romer, newton_to_celsius, + newton_to_delisle, newton_to_fahrenheit, newton_to_kelvin, newton_to_rankine, + newton_to_reaumur, newton_to_romer, rankine_to_celsius, rankine_to_delisle, + rankine_to_fahrenheit, rankine_to_kelvin, rankine_to_newton, rankine_to_reaumur, + rankine_to_romer, reaumur_to_celsius, reaumur_to_delisle, reaumur_to_fahrenheit, + reaumur_to_kelvin, reaumur_to_newton, reaumur_to_rankine, reaumur_to_romer, romer_to_celsius, + romer_to_delisle, romer_to_fahrenheit, romer_to_kelvin, romer_to_newton, romer_to_rankine, + romer_to_reaumur, +}; pub use self::time_units::convert_time; diff --git a/src/conversions/temperature.rs b/src/conversions/temperature.rs new file mode 100644 index 00000000000..759a6c61d1c --- /dev/null +++ b/src/conversions/temperature.rs @@ -0,0 +1,431 @@ +//! Convert between different units of temperature +//! +//! Supports conversions between 8 temperature scales: +//! - Kelvin (K) - SI base unit, absolute scale +//! - Celsius (°C) - Standard metric scale +//! - Fahrenheit (°F) - Imperial scale +//! - Rankine (°R) - Absolute Fahrenheit scale +//! - Delisle (°De) - Historical inverted scale (higher values = colder) +//! - Newton (°N) - Historical scale by Isaac Newton +//! - Réaumur (°Ré) - Historical European scale +//! - Rømer (°Rø) - Historical Danish scale + +// ============================================================================= +// CELSIUS CONVERSIONS +// ============================================================================= + +pub fn celsius_to_fahrenheit(celsius: f64) -> f64 { + (celsius * 9.0 / 5.0) + 32.0 +} + +pub fn celsius_to_kelvin(celsius: f64) -> f64 { + celsius + 273.15 +} + +pub fn celsius_to_rankine(celsius: f64) -> f64 { + (celsius + 273.15) * 9.0 / 5.0 +} + +pub fn celsius_to_delisle(celsius: f64) -> f64 { + (100.0 - celsius) * 3.0 / 2.0 +} + +pub fn celsius_to_newton(celsius: f64) -> f64 { + celsius * 33.0 / 100.0 +} + +pub fn celsius_to_reaumur(celsius: f64) -> f64 { + celsius * 4.0 / 5.0 +} + +pub fn celsius_to_romer(celsius: f64) -> f64 { + celsius * 21.0 / 40.0 + 7.5 +} + +// ============================================================================= +// FAHRENHEIT CONVERSIONS +// ============================================================================= + +pub fn fahrenheit_to_celsius(fahrenheit: f64) -> f64 { + (fahrenheit - 32.0) * 5.0 / 9.0 +} + +pub fn fahrenheit_to_kelvin(fahrenheit: f64) -> f64 { + (fahrenheit + 459.67) * 5.0 / 9.0 +} + +pub fn fahrenheit_to_rankine(fahrenheit: f64) -> f64 { + fahrenheit + 459.67 +} + +pub fn fahrenheit_to_delisle(fahrenheit: f64) -> f64 { + (212.0 - fahrenheit) * 5.0 / 6.0 +} + +pub fn fahrenheit_to_newton(fahrenheit: f64) -> f64 { + (fahrenheit - 32.0) * 11.0 / 60.0 +} + +pub fn fahrenheit_to_reaumur(fahrenheit: f64) -> f64 { + (fahrenheit - 32.0) * 4.0 / 9.0 +} + +pub fn fahrenheit_to_romer(fahrenheit: f64) -> f64 { + (fahrenheit - 32.0) * 7.0 / 24.0 + 7.5 +} + +// ============================================================================= +// KELVIN CONVERSIONS +// ============================================================================= + +pub fn kelvin_to_celsius(kelvin: f64) -> f64 { + kelvin - 273.15 +} + +pub fn kelvin_to_fahrenheit(kelvin: f64) -> f64 { + kelvin * 9.0 / 5.0 - 459.67 +} + +pub fn kelvin_to_rankine(kelvin: f64) -> f64 { + kelvin * 9.0 / 5.0 +} + +pub fn kelvin_to_delisle(kelvin: f64) -> f64 { + (373.15 - kelvin) * 3.0 / 2.0 +} + +pub fn kelvin_to_newton(kelvin: f64) -> f64 { + (kelvin - 273.15) * 33.0 / 100.0 +} + +pub fn kelvin_to_reaumur(kelvin: f64) -> f64 { + (kelvin - 273.15) * 4.0 / 5.0 +} + +pub fn kelvin_to_romer(kelvin: f64) -> f64 { + (kelvin - 273.15) * 21.0 / 40.0 + 7.5 +} + +// ============================================================================= +// RANKINE CONVERSIONS +// ============================================================================= + +pub fn rankine_to_celsius(rankine: f64) -> f64 { + (rankine - 491.67) * 5.0 / 9.0 +} + +pub fn rankine_to_fahrenheit(rankine: f64) -> f64 { + rankine - 459.67 +} + +pub fn rankine_to_kelvin(rankine: f64) -> f64 { + rankine * 5.0 / 9.0 +} + +pub fn rankine_to_delisle(rankine: f64) -> f64 { + (671.67 - rankine) * 5.0 / 6.0 +} + +pub fn rankine_to_newton(rankine: f64) -> f64 { + (rankine - 491.67) * 11.0 / 60.0 +} + +pub fn rankine_to_reaumur(rankine: f64) -> f64 { + (rankine - 491.67) * 4.0 / 9.0 +} + +pub fn rankine_to_romer(rankine: f64) -> f64 { + (rankine - 491.67) * 7.0 / 24.0 + 7.5 +} + +// ============================================================================= +// DELISLE CONVERSIONS +// ============================================================================= + +pub fn delisle_to_celsius(delisle: f64) -> f64 { + 100.0 - delisle * 2.0 / 3.0 +} + +pub fn delisle_to_fahrenheit(delisle: f64) -> f64 { + 212.0 - delisle * 6.0 / 5.0 +} + +pub fn delisle_to_kelvin(delisle: f64) -> f64 { + 373.15 - delisle * 2.0 / 3.0 +} + +pub fn delisle_to_rankine(delisle: f64) -> f64 { + 671.67 - delisle * 6.0 / 5.0 +} + +pub fn delisle_to_newton(delisle: f64) -> f64 { + 33.0 - delisle * 11.0 / 50.0 +} + +pub fn delisle_to_reaumur(delisle: f64) -> f64 { + 80.0 - delisle * 8.0 / 15.0 +} + +pub fn delisle_to_romer(delisle: f64) -> f64 { + 60.0 - delisle * 7.0 / 20.0 +} + +// ============================================================================= +// NEWTON CONVERSIONS +// ============================================================================= + +pub fn newton_to_celsius(newton: f64) -> f64 { + newton * 100.0 / 33.0 +} + +pub fn newton_to_fahrenheit(newton: f64) -> f64 { + newton * 60.0 / 11.0 + 32.0 +} + +pub fn newton_to_kelvin(newton: f64) -> f64 { + newton * 100.0 / 33.0 + 273.15 +} + +pub fn newton_to_rankine(newton: f64) -> f64 { + newton * 60.0 / 11.0 + 491.67 +} + +pub fn newton_to_delisle(newton: f64) -> f64 { + (33.0 - newton) * 50.0 / 11.0 +} + +pub fn newton_to_reaumur(newton: f64) -> f64 { + newton * 80.0 / 33.0 +} + +pub fn newton_to_romer(newton: f64) -> f64 { + newton * 35.0 / 22.0 + 7.5 +} + +// ============================================================================= +// RÉAUMUR CONVERSIONS +// ============================================================================= + +pub fn reaumur_to_celsius(reaumur: f64) -> f64 { + reaumur * 5.0 / 4.0 +} + +pub fn reaumur_to_fahrenheit(reaumur: f64) -> f64 { + reaumur * 9.0 / 4.0 + 32.0 +} + +pub fn reaumur_to_kelvin(reaumur: f64) -> f64 { + reaumur * 5.0 / 4.0 + 273.15 +} + +pub fn reaumur_to_rankine(reaumur: f64) -> f64 { + reaumur * 9.0 / 4.0 + 491.67 +} + +pub fn reaumur_to_delisle(reaumur: f64) -> f64 { + (80.0 - reaumur) * 15.0 / 8.0 +} + +pub fn reaumur_to_newton(reaumur: f64) -> f64 { + reaumur * 33.0 / 80.0 +} + +pub fn reaumur_to_romer(reaumur: f64) -> f64 { + reaumur * 21.0 / 32.0 + 7.5 +} + +// ============================================================================= +// RØMER CONVERSIONS +// ============================================================================= + +pub fn romer_to_celsius(romer: f64) -> f64 { + (romer - 7.5) * 40.0 / 21.0 +} + +pub fn romer_to_fahrenheit(romer: f64) -> f64 { + (romer - 7.5) * 24.0 / 7.0 + 32.0 +} + +pub fn romer_to_kelvin(romer: f64) -> f64 { + (romer - 7.5) * 40.0 / 21.0 + 273.15 +} + +pub fn romer_to_rankine(romer: f64) -> f64 { + (romer - 7.5) * 24.0 / 7.0 + 491.67 +} + +pub fn romer_to_delisle(romer: f64) -> f64 { + (60.0 - romer) * 20.0 / 7.0 +} + +pub fn romer_to_newton(romer: f64) -> f64 { + (romer - 7.5) * 22.0 / 35.0 +} + +pub fn romer_to_reaumur(romer: f64) -> f64 { + (romer - 7.5) * 32.0 / 21.0 +} + +// ============================================================================= +// TESTS +// ============================================================================= + +#[cfg(test)] +mod tests { + use super::*; + + const EPSILON: f64 = 1e-10; + + fn approx_eq(a: f64, b: f64) -> bool { + (a - b).abs() < EPSILON + } + + #[test] + fn test_celsius_conversions() { + assert!(approx_eq(celsius_to_fahrenheit(0.0), 32.0)); + assert!(approx_eq(celsius_to_fahrenheit(100.0), 212.0)); + assert!(approx_eq(celsius_to_kelvin(0.0), 273.15)); + assert!(approx_eq(celsius_to_rankine(0.0), 491.67)); + assert!(approx_eq(celsius_to_delisle(0.0), 150.0)); + assert!(approx_eq(celsius_to_newton(0.0), 0.0)); + assert!(approx_eq(celsius_to_reaumur(0.0), 0.0)); + assert!(approx_eq(celsius_to_romer(0.0), 7.5)); + } + + #[test] + fn test_fahrenheit_conversions() { + assert!(approx_eq(fahrenheit_to_celsius(32.0), 0.0)); + assert!(approx_eq(fahrenheit_to_celsius(212.0), 100.0)); + assert!(approx_eq(fahrenheit_to_kelvin(32.0), 273.15)); + assert!(approx_eq(fahrenheit_to_rankine(32.0), 491.67)); + assert!(approx_eq(fahrenheit_to_delisle(32.0), 150.0)); + assert!(approx_eq(fahrenheit_to_newton(32.0), 0.0)); + assert!(approx_eq(fahrenheit_to_reaumur(32.0), 0.0)); + assert!(approx_eq(fahrenheit_to_romer(32.0), 7.5)); + } + + #[test] + fn test_kelvin_conversions() { + assert!(approx_eq(kelvin_to_celsius(273.15), 0.0)); + assert!(approx_eq(kelvin_to_fahrenheit(273.15), 32.0)); + assert!(approx_eq(kelvin_to_rankine(273.15), 491.67)); + assert!(approx_eq(kelvin_to_delisle(273.15), 150.0)); + assert!(approx_eq(kelvin_to_newton(273.15), 0.0)); + assert!(approx_eq(kelvin_to_reaumur(273.15), 0.0)); + assert!(approx_eq(kelvin_to_romer(273.15), 7.5)); + } + + #[test] + fn test_rankine_conversions() { + assert!(approx_eq(rankine_to_celsius(491.67), 0.0)); + assert!(approx_eq(rankine_to_fahrenheit(491.67), 32.0)); + assert!(approx_eq(rankine_to_kelvin(491.67), 273.15)); + assert!(approx_eq(rankine_to_delisle(491.67), 150.0)); + assert!(approx_eq(rankine_to_newton(491.67), 0.0)); + assert!(approx_eq(rankine_to_reaumur(491.67), 0.0)); + assert!(approx_eq(rankine_to_romer(491.67), 7.5)); + } + + #[test] + fn test_delisle_conversions() { + assert!(approx_eq(delisle_to_celsius(150.0), 0.0)); + assert!(approx_eq(delisle_to_fahrenheit(150.0), 32.0)); + assert!(approx_eq(delisle_to_kelvin(150.0), 273.15)); + assert!(approx_eq(delisle_to_rankine(150.0), 491.67)); + assert!(approx_eq(delisle_to_newton(150.0), 0.0)); + assert!(approx_eq(delisle_to_reaumur(150.0), 0.0)); + assert!(approx_eq(delisle_to_romer(150.0), 7.5)); + } + + #[test] + fn test_newton_conversions() { + assert!(approx_eq(newton_to_celsius(0.0), 0.0)); + assert!(approx_eq(newton_to_fahrenheit(0.0), 32.0)); + assert!(approx_eq(newton_to_kelvin(0.0), 273.15)); + assert!(approx_eq(newton_to_rankine(0.0), 491.67)); + assert!(approx_eq(newton_to_delisle(0.0), 150.0)); + assert!(approx_eq(newton_to_reaumur(0.0), 0.0)); + assert!(approx_eq(newton_to_romer(0.0), 7.5)); + } + + #[test] + fn test_reaumur_conversions() { + assert!(approx_eq(reaumur_to_celsius(0.0), 0.0)); + assert!(approx_eq(reaumur_to_fahrenheit(0.0), 32.0)); + assert!(approx_eq(reaumur_to_kelvin(0.0), 273.15)); + assert!(approx_eq(reaumur_to_rankine(0.0), 491.67)); + assert!(approx_eq(reaumur_to_delisle(0.0), 150.0)); + assert!(approx_eq(reaumur_to_newton(0.0), 0.0)); + assert!(approx_eq(reaumur_to_romer(0.0), 7.5)); + } + + #[test] + fn test_romer_conversions() { + assert!(approx_eq(romer_to_celsius(7.5), 0.0)); + assert!(approx_eq(romer_to_fahrenheit(7.5), 32.0)); + assert!(approx_eq(romer_to_kelvin(7.5), 273.15)); + assert!(approx_eq(romer_to_rankine(7.5), 491.67)); + assert!(approx_eq(romer_to_delisle(7.5), 150.0)); + assert!(approx_eq(romer_to_newton(7.5), 0.0)); + assert!(approx_eq(romer_to_reaumur(7.5), 0.0)); + } + + #[test] + fn test_round_trip_conversions() { + let temp_c = 25.0; + + let temp_f = celsius_to_fahrenheit(temp_c); + assert!(approx_eq(fahrenheit_to_celsius(temp_f), temp_c)); + + let temp_k = celsius_to_kelvin(temp_c); + assert!(approx_eq(kelvin_to_celsius(temp_k), temp_c)); + + let temp_r = celsius_to_rankine(temp_c); + assert!(approx_eq(rankine_to_celsius(temp_r), temp_c)); + + let temp_de = celsius_to_delisle(temp_c); + assert!(approx_eq(delisle_to_celsius(temp_de), temp_c)); + + let temp_n = celsius_to_newton(temp_c); + assert!(approx_eq(newton_to_celsius(temp_n), temp_c)); + + let temp_re = celsius_to_reaumur(temp_c); + assert!(approx_eq(reaumur_to_celsius(temp_re), temp_c)); + + let temp_ro = celsius_to_romer(temp_c); + assert!(approx_eq(romer_to_celsius(temp_ro), temp_c)); + } + + #[test] + fn test_special_temperatures() { + // Absolute zero + assert!(approx_eq(kelvin_to_celsius(0.0), -273.15)); + assert!(approx_eq(kelvin_to_fahrenheit(0.0), -459.67)); + + // Water freezing point + assert!(approx_eq(celsius_to_fahrenheit(0.0), 32.0)); + assert!(approx_eq(celsius_to_kelvin(0.0), 273.15)); + + // Water boiling point + assert!(approx_eq(celsius_to_fahrenheit(100.0), 212.0)); + assert!(approx_eq(celsius_to_kelvin(100.0), 373.15)); + + // Celsius equals Fahrenheit + assert!(approx_eq(celsius_to_fahrenheit(-40.0), -40.0)); + } + + #[test] + fn test_historical_scales() { + // Delisle (inverted scale) + assert!(approx_eq(celsius_to_delisle(100.0), 0.0)); + assert!(approx_eq(delisle_to_celsius(0.0), 100.0)); + + // Newton scale + assert!(approx_eq(celsius_to_newton(100.0), 33.0)); + assert!(approx_eq(newton_to_celsius(33.0), 100.0)); + + // Rømer scale + assert!(approx_eq(celsius_to_romer(100.0), 60.0)); + assert!(approx_eq(romer_to_celsius(60.0), 100.0)); + } +} From 292d6d3b95f42160d4feefc73d52d4c52b555975 Mon Sep 17 00:00:00 2001 From: Ali Alimohammadi <41567902+AliAlimohammadi@users.noreply.github.com> Date: Mon, 19 Jan 2026 19:15:28 -0800 Subject: [PATCH 2/5] Update mod.rs --- src/conversions/mod.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/conversions/mod.rs b/src/conversions/mod.rs index 038ac12a2c8..77824de6a90 100644 --- a/src/conversions/mod.rs +++ b/src/conversions/mod.rs @@ -17,8 +17,8 @@ mod rgb_cmyk_conversion; mod rgb_hsv_conversion; mod roman_numerals; mod speed; -mod time_units; mod temperature; +mod time_units; pub use self::binary_to_decimal::binary_to_decimal; pub use self::binary_to_hexadecimal::binary_to_hexadecimal; @@ -41,7 +41,6 @@ pub use self::rgb_cmyk_conversion::rgb_to_cmyk; pub use self::rgb_hsv_conversion::{hsv_to_rgb, rgb_to_hsv, ColorError, Hsv, Rgb}; pub use self::roman_numerals::{int_to_roman, roman_to_int}; pub use self::speed::{convert_speed, SpeedUnit}; -pub use self::time_units::convert_time; pub use self::temperature::{ celsius_to_delisle, celsius_to_fahrenheit, celsius_to_kelvin, celsius_to_newton, celsius_to_rankine, celsius_to_reaumur, celsius_to_romer, delisle_to_celsius, @@ -57,4 +56,5 @@ pub use self::temperature::{ reaumur_to_kelvin, reaumur_to_newton, reaumur_to_rankine, reaumur_to_romer, romer_to_celsius, romer_to_delisle, romer_to_fahrenheit, romer_to_kelvin, romer_to_newton, romer_to_rankine, romer_to_reaumur, -}; \ No newline at end of file +}; +pub use self::time_units::convert_time; From ddbd387e2b9b67de90e260a3d2a514d84a1e226e Mon Sep 17 00:00:00 2001 From: Ali Alimohammadi <41567902+AliAlimohammadi@users.noreply.github.com> Date: Mon, 19 Jan 2026 19:26:17 -0800 Subject: [PATCH 3/5] Update mod.rs --- src/conversions/mod.rs | 17 +---------------- 1 file changed, 1 insertion(+), 16 deletions(-) diff --git a/src/conversions/mod.rs b/src/conversions/mod.rs index 77824de6a90..99fc907e919 100644 --- a/src/conversions/mod.rs +++ b/src/conversions/mod.rs @@ -41,20 +41,5 @@ pub use self::rgb_cmyk_conversion::rgb_to_cmyk; pub use self::rgb_hsv_conversion::{hsv_to_rgb, rgb_to_hsv, ColorError, Hsv, Rgb}; pub use self::roman_numerals::{int_to_roman, roman_to_int}; pub use self::speed::{convert_speed, SpeedUnit}; -pub use self::temperature::{ - celsius_to_delisle, celsius_to_fahrenheit, celsius_to_kelvin, celsius_to_newton, - celsius_to_rankine, celsius_to_reaumur, celsius_to_romer, delisle_to_celsius, - delisle_to_fahrenheit, delisle_to_kelvin, delisle_to_newton, delisle_to_rankine, - delisle_to_reaumur, delisle_to_romer, fahrenheit_to_celsius, fahrenheit_to_delisle, - fahrenheit_to_kelvin, fahrenheit_to_newton, fahrenheit_to_rankine, fahrenheit_to_reaumur, - fahrenheit_to_romer, kelvin_to_celsius, kelvin_to_delisle, kelvin_to_fahrenheit, - kelvin_to_newton, kelvin_to_rankine, kelvin_to_reaumur, kelvin_to_romer, newton_to_celsius, - newton_to_delisle, newton_to_fahrenheit, newton_to_kelvin, newton_to_rankine, - newton_to_reaumur, newton_to_romer, rankine_to_celsius, rankine_to_delisle, - rankine_to_fahrenheit, rankine_to_kelvin, rankine_to_newton, rankine_to_reaumur, - rankine_to_romer, reaumur_to_celsius, reaumur_to_delisle, reaumur_to_fahrenheit, - reaumur_to_kelvin, reaumur_to_newton, reaumur_to_rankine, reaumur_to_romer, romer_to_celsius, - romer_to_delisle, romer_to_fahrenheit, romer_to_kelvin, romer_to_newton, romer_to_rankine, - romer_to_reaumur, -}; +pub use self::temperature::{convert_temperature, TemperatureUnit}; pub use self::time_units::convert_time; From ff73519f60dc3dcbeb4467780212b6e35ab74830 Mon Sep 17 00:00:00 2001 From: Ali Alimohammadi <41567902+AliAlimohammadi@users.noreply.github.com> Date: Mon, 19 Jan 2026 19:27:41 -0800 Subject: [PATCH 4/5] Update temperature.rs --- src/conversions/temperature.rs | 566 ++++++++++++--------------------- 1 file changed, 197 insertions(+), 369 deletions(-) diff --git a/src/conversions/temperature.rs b/src/conversions/temperature.rs index 759a6c61d1c..b48c0da8b7e 100644 --- a/src/conversions/temperature.rs +++ b/src/conversions/temperature.rs @@ -1,6 +1,6 @@ //! Convert between different units of temperature //! -//! Supports conversions between 8 temperature scales: +//! Supports conversions between 8 temperature scales using Kelvin as an intermediary: //! - Kelvin (K) - SI base unit, absolute scale //! - Celsius (°C) - Standard metric scale //! - Fahrenheit (°F) - Imperial scale @@ -10,266 +10,51 @@ //! - Réaumur (°Ré) - Historical European scale //! - Rømer (°Rø) - Historical Danish scale -// ============================================================================= -// CELSIUS CONVERSIONS -// ============================================================================= - -pub fn celsius_to_fahrenheit(celsius: f64) -> f64 { - (celsius * 9.0 / 5.0) + 32.0 -} - -pub fn celsius_to_kelvin(celsius: f64) -> f64 { - celsius + 273.15 -} - -pub fn celsius_to_rankine(celsius: f64) -> f64 { - (celsius + 273.15) * 9.0 / 5.0 -} - -pub fn celsius_to_delisle(celsius: f64) -> f64 { - (100.0 - celsius) * 3.0 / 2.0 -} - -pub fn celsius_to_newton(celsius: f64) -> f64 { - celsius * 33.0 / 100.0 -} - -pub fn celsius_to_reaumur(celsius: f64) -> f64 { - celsius * 4.0 / 5.0 -} - -pub fn celsius_to_romer(celsius: f64) -> f64 { - celsius * 21.0 / 40.0 + 7.5 -} - -// ============================================================================= -// FAHRENHEIT CONVERSIONS -// ============================================================================= - -pub fn fahrenheit_to_celsius(fahrenheit: f64) -> f64 { - (fahrenheit - 32.0) * 5.0 / 9.0 -} - -pub fn fahrenheit_to_kelvin(fahrenheit: f64) -> f64 { - (fahrenheit + 459.67) * 5.0 / 9.0 -} - -pub fn fahrenheit_to_rankine(fahrenheit: f64) -> f64 { - fahrenheit + 459.67 -} - -pub fn fahrenheit_to_delisle(fahrenheit: f64) -> f64 { - (212.0 - fahrenheit) * 5.0 / 6.0 -} - -pub fn fahrenheit_to_newton(fahrenheit: f64) -> f64 { - (fahrenheit - 32.0) * 11.0 / 60.0 -} - -pub fn fahrenheit_to_reaumur(fahrenheit: f64) -> f64 { - (fahrenheit - 32.0) * 4.0 / 9.0 -} - -pub fn fahrenheit_to_romer(fahrenheit: f64) -> f64 { - (fahrenheit - 32.0) * 7.0 / 24.0 + 7.5 -} - -// ============================================================================= -// KELVIN CONVERSIONS -// ============================================================================= - -pub fn kelvin_to_celsius(kelvin: f64) -> f64 { - kelvin - 273.15 -} - -pub fn kelvin_to_fahrenheit(kelvin: f64) -> f64 { - kelvin * 9.0 / 5.0 - 459.67 -} - -pub fn kelvin_to_rankine(kelvin: f64) -> f64 { - kelvin * 9.0 / 5.0 -} - -pub fn kelvin_to_delisle(kelvin: f64) -> f64 { - (373.15 - kelvin) * 3.0 / 2.0 -} - -pub fn kelvin_to_newton(kelvin: f64) -> f64 { - (kelvin - 273.15) * 33.0 / 100.0 -} - -pub fn kelvin_to_reaumur(kelvin: f64) -> f64 { - (kelvin - 273.15) * 4.0 / 5.0 -} - -pub fn kelvin_to_romer(kelvin: f64) -> f64 { - (kelvin - 273.15) * 21.0 / 40.0 + 7.5 -} - -// ============================================================================= -// RANKINE CONVERSIONS -// ============================================================================= - -pub fn rankine_to_celsius(rankine: f64) -> f64 { - (rankine - 491.67) * 5.0 / 9.0 -} - -pub fn rankine_to_fahrenheit(rankine: f64) -> f64 { - rankine - 459.67 -} - -pub fn rankine_to_kelvin(rankine: f64) -> f64 { - rankine * 5.0 / 9.0 -} - -pub fn rankine_to_delisle(rankine: f64) -> f64 { - (671.67 - rankine) * 5.0 / 6.0 -} - -pub fn rankine_to_newton(rankine: f64) -> f64 { - (rankine - 491.67) * 11.0 / 60.0 -} - -pub fn rankine_to_reaumur(rankine: f64) -> f64 { - (rankine - 491.67) * 4.0 / 9.0 -} - -pub fn rankine_to_romer(rankine: f64) -> f64 { - (rankine - 491.67) * 7.0 / 24.0 + 7.5 -} - -// ============================================================================= -// DELISLE CONVERSIONS -// ============================================================================= - -pub fn delisle_to_celsius(delisle: f64) -> f64 { - 100.0 - delisle * 2.0 / 3.0 -} - -pub fn delisle_to_fahrenheit(delisle: f64) -> f64 { - 212.0 - delisle * 6.0 / 5.0 -} - -pub fn delisle_to_kelvin(delisle: f64) -> f64 { - 373.15 - delisle * 2.0 / 3.0 -} - -pub fn delisle_to_rankine(delisle: f64) -> f64 { - 671.67 - delisle * 6.0 / 5.0 -} - -pub fn delisle_to_newton(delisle: f64) -> f64 { - 33.0 - delisle * 11.0 / 50.0 -} - -pub fn delisle_to_reaumur(delisle: f64) -> f64 { - 80.0 - delisle * 8.0 / 15.0 -} - -pub fn delisle_to_romer(delisle: f64) -> f64 { - 60.0 - delisle * 7.0 / 20.0 -} - -// ============================================================================= -// NEWTON CONVERSIONS -// ============================================================================= - -pub fn newton_to_celsius(newton: f64) -> f64 { - newton * 100.0 / 33.0 -} - -pub fn newton_to_fahrenheit(newton: f64) -> f64 { - newton * 60.0 / 11.0 + 32.0 -} - -pub fn newton_to_kelvin(newton: f64) -> f64 { - newton * 100.0 / 33.0 + 273.15 -} - -pub fn newton_to_rankine(newton: f64) -> f64 { - newton * 60.0 / 11.0 + 491.67 -} - -pub fn newton_to_delisle(newton: f64) -> f64 { - (33.0 - newton) * 50.0 / 11.0 -} - -pub fn newton_to_reaumur(newton: f64) -> f64 { - newton * 80.0 / 33.0 -} - -pub fn newton_to_romer(newton: f64) -> f64 { - newton * 35.0 / 22.0 + 7.5 -} - -// ============================================================================= -// RÉAUMUR CONVERSIONS -// ============================================================================= - -pub fn reaumur_to_celsius(reaumur: f64) -> f64 { - reaumur * 5.0 / 4.0 -} - -pub fn reaumur_to_fahrenheit(reaumur: f64) -> f64 { - reaumur * 9.0 / 4.0 + 32.0 -} - -pub fn reaumur_to_kelvin(reaumur: f64) -> f64 { - reaumur * 5.0 / 4.0 + 273.15 -} - -pub fn reaumur_to_rankine(reaumur: f64) -> f64 { - reaumur * 9.0 / 4.0 + 491.67 -} - -pub fn reaumur_to_delisle(reaumur: f64) -> f64 { - (80.0 - reaumur) * 15.0 / 8.0 -} - -pub fn reaumur_to_newton(reaumur: f64) -> f64 { - reaumur * 33.0 / 80.0 -} - -pub fn reaumur_to_romer(reaumur: f64) -> f64 { - reaumur * 21.0 / 32.0 + 7.5 -} - -// ============================================================================= -// RØMER CONVERSIONS -// ============================================================================= - -pub fn romer_to_celsius(romer: f64) -> f64 { - (romer - 7.5) * 40.0 / 21.0 -} - -pub fn romer_to_fahrenheit(romer: f64) -> f64 { - (romer - 7.5) * 24.0 / 7.0 + 32.0 -} - -pub fn romer_to_kelvin(romer: f64) -> f64 { - (romer - 7.5) * 40.0 / 21.0 + 273.15 -} - -pub fn romer_to_rankine(romer: f64) -> f64 { - (romer - 7.5) * 24.0 / 7.0 + 491.67 -} - -pub fn romer_to_delisle(romer: f64) -> f64 { - (60.0 - romer) * 20.0 / 7.0 -} +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +pub enum TemperatureUnit { + Kelvin, + Celsius, + Fahrenheit, + Rankine, + Delisle, + Newton, + Reaumur, + Romer, +} + +impl TemperatureUnit { + fn to_kelvin(self, value: f64) -> f64 { + match self { + TemperatureUnit::Kelvin => value, + TemperatureUnit::Celsius => value + 273.15, + TemperatureUnit::Fahrenheit => (value + 459.67) * 5.0 / 9.0, + TemperatureUnit::Rankine => value * 5.0 / 9.0, + TemperatureUnit::Delisle => 373.15 - value * 2.0 / 3.0, + TemperatureUnit::Newton => value * 100.0 / 33.0 + 273.15, + TemperatureUnit::Reaumur => value * 5.0 / 4.0 + 273.15, + TemperatureUnit::Romer => (value - 7.5) * 40.0 / 21.0 + 273.15, + } + } -pub fn romer_to_newton(romer: f64) -> f64 { - (romer - 7.5) * 22.0 / 35.0 + fn kelvin_to_unit(self, kelvin: f64) -> f64 { + match self { + TemperatureUnit::Kelvin => kelvin, + TemperatureUnit::Celsius => kelvin - 273.15, + TemperatureUnit::Fahrenheit => kelvin * 9.0 / 5.0 - 459.67, + TemperatureUnit::Rankine => kelvin * 9.0 / 5.0, + TemperatureUnit::Delisle => (373.15 - kelvin) * 3.0 / 2.0, + TemperatureUnit::Newton => (kelvin - 273.15) * 33.0 / 100.0, + TemperatureUnit::Reaumur => (kelvin - 273.15) * 4.0 / 5.0, + TemperatureUnit::Romer => (kelvin - 273.15) * 21.0 / 40.0 + 7.5, + } + } } -pub fn romer_to_reaumur(romer: f64) -> f64 { - (romer - 7.5) * 32.0 / 21.0 +pub fn convert_temperature(value: f64, from: TemperatureUnit, to: TemperatureUnit) -> f64 { + let kelvin = from.to_kelvin(value); + to.kelvin_to_unit(kelvin) } -// ============================================================================= -// TESTS -// ============================================================================= - #[cfg(test)] mod tests { use super::*; @@ -282,150 +67,193 @@ mod tests { #[test] fn test_celsius_conversions() { - assert!(approx_eq(celsius_to_fahrenheit(0.0), 32.0)); - assert!(approx_eq(celsius_to_fahrenheit(100.0), 212.0)); - assert!(approx_eq(celsius_to_kelvin(0.0), 273.15)); - assert!(approx_eq(celsius_to_rankine(0.0), 491.67)); - assert!(approx_eq(celsius_to_delisle(0.0), 150.0)); - assert!(approx_eq(celsius_to_newton(0.0), 0.0)); - assert!(approx_eq(celsius_to_reaumur(0.0), 0.0)); - assert!(approx_eq(celsius_to_romer(0.0), 7.5)); + assert!(approx_eq( + convert_temperature(0.0, TemperatureUnit::Celsius, TemperatureUnit::Fahrenheit), + 32.0 + )); + assert!(approx_eq( + convert_temperature(100.0, TemperatureUnit::Celsius, TemperatureUnit::Fahrenheit), + 212.0 + )); + assert!(approx_eq( + convert_temperature(0.0, TemperatureUnit::Celsius, TemperatureUnit::Kelvin), + 273.15 + )); + assert!(approx_eq( + convert_temperature(0.0, TemperatureUnit::Celsius, TemperatureUnit::Rankine), + 491.67 + )); + assert!(approx_eq( + convert_temperature(0.0, TemperatureUnit::Celsius, TemperatureUnit::Delisle), + 150.0 + )); + assert!(approx_eq( + convert_temperature(0.0, TemperatureUnit::Celsius, TemperatureUnit::Newton), + 0.0 + )); + assert!(approx_eq( + convert_temperature(0.0, TemperatureUnit::Celsius, TemperatureUnit::Reaumur), + 0.0 + )); + assert!(approx_eq( + convert_temperature(0.0, TemperatureUnit::Celsius, TemperatureUnit::Romer), + 7.5 + )); } #[test] fn test_fahrenheit_conversions() { - assert!(approx_eq(fahrenheit_to_celsius(32.0), 0.0)); - assert!(approx_eq(fahrenheit_to_celsius(212.0), 100.0)); - assert!(approx_eq(fahrenheit_to_kelvin(32.0), 273.15)); - assert!(approx_eq(fahrenheit_to_rankine(32.0), 491.67)); - assert!(approx_eq(fahrenheit_to_delisle(32.0), 150.0)); - assert!(approx_eq(fahrenheit_to_newton(32.0), 0.0)); - assert!(approx_eq(fahrenheit_to_reaumur(32.0), 0.0)); - assert!(approx_eq(fahrenheit_to_romer(32.0), 7.5)); + assert!(approx_eq( + convert_temperature(32.0, TemperatureUnit::Fahrenheit, TemperatureUnit::Celsius), + 0.0 + )); + assert!(approx_eq( + convert_temperature(212.0, TemperatureUnit::Fahrenheit, TemperatureUnit::Celsius), + 100.0 + )); + assert!(approx_eq( + convert_temperature(32.0, TemperatureUnit::Fahrenheit, TemperatureUnit::Kelvin), + 273.15 + )); + assert!(approx_eq( + convert_temperature(32.0, TemperatureUnit::Fahrenheit, TemperatureUnit::Rankine), + 491.67 + )); } #[test] fn test_kelvin_conversions() { - assert!(approx_eq(kelvin_to_celsius(273.15), 0.0)); - assert!(approx_eq(kelvin_to_fahrenheit(273.15), 32.0)); - assert!(approx_eq(kelvin_to_rankine(273.15), 491.67)); - assert!(approx_eq(kelvin_to_delisle(273.15), 150.0)); - assert!(approx_eq(kelvin_to_newton(273.15), 0.0)); - assert!(approx_eq(kelvin_to_reaumur(273.15), 0.0)); - assert!(approx_eq(kelvin_to_romer(273.15), 7.5)); - } - - #[test] - fn test_rankine_conversions() { - assert!(approx_eq(rankine_to_celsius(491.67), 0.0)); - assert!(approx_eq(rankine_to_fahrenheit(491.67), 32.0)); - assert!(approx_eq(rankine_to_kelvin(491.67), 273.15)); - assert!(approx_eq(rankine_to_delisle(491.67), 150.0)); - assert!(approx_eq(rankine_to_newton(491.67), 0.0)); - assert!(approx_eq(rankine_to_reaumur(491.67), 0.0)); - assert!(approx_eq(rankine_to_romer(491.67), 7.5)); - } - - #[test] - fn test_delisle_conversions() { - assert!(approx_eq(delisle_to_celsius(150.0), 0.0)); - assert!(approx_eq(delisle_to_fahrenheit(150.0), 32.0)); - assert!(approx_eq(delisle_to_kelvin(150.0), 273.15)); - assert!(approx_eq(delisle_to_rankine(150.0), 491.67)); - assert!(approx_eq(delisle_to_newton(150.0), 0.0)); - assert!(approx_eq(delisle_to_reaumur(150.0), 0.0)); - assert!(approx_eq(delisle_to_romer(150.0), 7.5)); - } - - #[test] - fn test_newton_conversions() { - assert!(approx_eq(newton_to_celsius(0.0), 0.0)); - assert!(approx_eq(newton_to_fahrenheit(0.0), 32.0)); - assert!(approx_eq(newton_to_kelvin(0.0), 273.15)); - assert!(approx_eq(newton_to_rankine(0.0), 491.67)); - assert!(approx_eq(newton_to_delisle(0.0), 150.0)); - assert!(approx_eq(newton_to_reaumur(0.0), 0.0)); - assert!(approx_eq(newton_to_romer(0.0), 7.5)); - } - - #[test] - fn test_reaumur_conversions() { - assert!(approx_eq(reaumur_to_celsius(0.0), 0.0)); - assert!(approx_eq(reaumur_to_fahrenheit(0.0), 32.0)); - assert!(approx_eq(reaumur_to_kelvin(0.0), 273.15)); - assert!(approx_eq(reaumur_to_rankine(0.0), 491.67)); - assert!(approx_eq(reaumur_to_delisle(0.0), 150.0)); - assert!(approx_eq(reaumur_to_newton(0.0), 0.0)); - assert!(approx_eq(reaumur_to_romer(0.0), 7.5)); - } - - #[test] - fn test_romer_conversions() { - assert!(approx_eq(romer_to_celsius(7.5), 0.0)); - assert!(approx_eq(romer_to_fahrenheit(7.5), 32.0)); - assert!(approx_eq(romer_to_kelvin(7.5), 273.15)); - assert!(approx_eq(romer_to_rankine(7.5), 491.67)); - assert!(approx_eq(romer_to_delisle(7.5), 150.0)); - assert!(approx_eq(romer_to_newton(7.5), 0.0)); - assert!(approx_eq(romer_to_reaumur(7.5), 0.0)); + assert!(approx_eq( + convert_temperature(273.15, TemperatureUnit::Kelvin, TemperatureUnit::Celsius), + 0.0 + )); + assert!(approx_eq( + convert_temperature(273.15, TemperatureUnit::Kelvin, TemperatureUnit::Fahrenheit), + 32.0 + )); + assert!(approx_eq( + convert_temperature(273.15, TemperatureUnit::Kelvin, TemperatureUnit::Rankine), + 491.67 + )); } #[test] fn test_round_trip_conversions() { - let temp_c = 25.0; - - let temp_f = celsius_to_fahrenheit(temp_c); - assert!(approx_eq(fahrenheit_to_celsius(temp_f), temp_c)); - - let temp_k = celsius_to_kelvin(temp_c); - assert!(approx_eq(kelvin_to_celsius(temp_k), temp_c)); - - let temp_r = celsius_to_rankine(temp_c); - assert!(approx_eq(rankine_to_celsius(temp_r), temp_c)); - - let temp_de = celsius_to_delisle(temp_c); - assert!(approx_eq(delisle_to_celsius(temp_de), temp_c)); - - let temp_n = celsius_to_newton(temp_c); - assert!(approx_eq(newton_to_celsius(temp_n), temp_c)); - - let temp_re = celsius_to_reaumur(temp_c); - assert!(approx_eq(reaumur_to_celsius(temp_re), temp_c)); - - let temp_ro = celsius_to_romer(temp_c); - assert!(approx_eq(romer_to_celsius(temp_ro), temp_c)); + let temp = 25.0; + let units = [ + TemperatureUnit::Celsius, + TemperatureUnit::Fahrenheit, + TemperatureUnit::Kelvin, + TemperatureUnit::Rankine, + TemperatureUnit::Delisle, + TemperatureUnit::Newton, + TemperatureUnit::Reaumur, + TemperatureUnit::Romer, + ]; + + for from_unit in units.iter() { + for to_unit in units.iter() { + let converted = convert_temperature(temp, *from_unit, *to_unit); + let back = convert_temperature(converted, *to_unit, *from_unit); + assert!( + approx_eq(back, temp), + "Round trip failed: {:?} -> {:?} -> {:?}: {} != {}", + from_unit, + to_unit, + from_unit, + back, + temp + ); + } + } } #[test] fn test_special_temperatures() { // Absolute zero - assert!(approx_eq(kelvin_to_celsius(0.0), -273.15)); - assert!(approx_eq(kelvin_to_fahrenheit(0.0), -459.67)); + assert!(approx_eq( + convert_temperature(0.0, TemperatureUnit::Kelvin, TemperatureUnit::Celsius), + -273.15 + )); + assert!(approx_eq( + convert_temperature(0.0, TemperatureUnit::Kelvin, TemperatureUnit::Fahrenheit), + -459.67 + )); // Water freezing point - assert!(approx_eq(celsius_to_fahrenheit(0.0), 32.0)); - assert!(approx_eq(celsius_to_kelvin(0.0), 273.15)); + assert!(approx_eq( + convert_temperature(0.0, TemperatureUnit::Celsius, TemperatureUnit::Fahrenheit), + 32.0 + )); + assert!(approx_eq( + convert_temperature(0.0, TemperatureUnit::Celsius, TemperatureUnit::Kelvin), + 273.15 + )); // Water boiling point - assert!(approx_eq(celsius_to_fahrenheit(100.0), 212.0)); - assert!(approx_eq(celsius_to_kelvin(100.0), 373.15)); + assert!(approx_eq( + convert_temperature(100.0, TemperatureUnit::Celsius, TemperatureUnit::Fahrenheit), + 212.0 + )); + assert!(approx_eq( + convert_temperature(100.0, TemperatureUnit::Celsius, TemperatureUnit::Kelvin), + 373.15 + )); // Celsius equals Fahrenheit - assert!(approx_eq(celsius_to_fahrenheit(-40.0), -40.0)); + assert!(approx_eq( + convert_temperature(-40.0, TemperatureUnit::Celsius, TemperatureUnit::Fahrenheit), + -40.0 + )); } #[test] fn test_historical_scales() { // Delisle (inverted scale) - assert!(approx_eq(celsius_to_delisle(100.0), 0.0)); - assert!(approx_eq(delisle_to_celsius(0.0), 100.0)); + assert!(approx_eq( + convert_temperature(100.0, TemperatureUnit::Celsius, TemperatureUnit::Delisle), + 0.0 + )); + assert!(approx_eq( + convert_temperature(0.0, TemperatureUnit::Delisle, TemperatureUnit::Celsius), + 100.0 + )); // Newton scale - assert!(approx_eq(celsius_to_newton(100.0), 33.0)); - assert!(approx_eq(newton_to_celsius(33.0), 100.0)); + assert!(approx_eq( + convert_temperature(100.0, TemperatureUnit::Celsius, TemperatureUnit::Newton), + 33.0 + )); + assert!(approx_eq( + convert_temperature(33.0, TemperatureUnit::Newton, TemperatureUnit::Celsius), + 100.0 + )); // Rømer scale - assert!(approx_eq(celsius_to_romer(100.0), 60.0)); - assert!(approx_eq(romer_to_celsius(60.0), 100.0)); + assert!(approx_eq( + convert_temperature(100.0, TemperatureUnit::Celsius, TemperatureUnit::Romer), + 60.0 + )); + assert!(approx_eq( + convert_temperature(60.0, TemperatureUnit::Romer, TemperatureUnit::Celsius), + 100.0 + )); + } + + #[test] + fn test_same_unit_conversion() { + let temp = 42.0; + for unit in [ + TemperatureUnit::Celsius, + TemperatureUnit::Fahrenheit, + TemperatureUnit::Kelvin, + TemperatureUnit::Rankine, + TemperatureUnit::Delisle, + TemperatureUnit::Newton, + TemperatureUnit::Reaumur, + TemperatureUnit::Romer, + ] { + assert!(approx_eq(convert_temperature(temp, unit, unit), temp)); + } } } From 4f3e46b0a3e9fed081f94b619071e39a7b508c02 Mon Sep 17 00:00:00 2001 From: Ali Alimohammadi <41567902+AliAlimohammadi@users.noreply.github.com> Date: Mon, 19 Jan 2026 19:30:44 -0800 Subject: [PATCH 5/5] Update temperature.rs --- src/conversions/temperature.rs | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/src/conversions/temperature.rs b/src/conversions/temperature.rs index b48c0da8b7e..ecb91f5ef88 100644 --- a/src/conversions/temperature.rs +++ b/src/conversions/temperature.rs @@ -157,12 +157,7 @@ mod tests { let back = convert_temperature(converted, *to_unit, *from_unit); assert!( approx_eq(back, temp), - "Round trip failed: {:?} -> {:?} -> {:?}: {} != {}", - from_unit, - to_unit, - from_unit, - back, - temp + "Round trip failed: {from_unit:?} -> {to_unit:?} -> {from_unit:?}: {back} != {temp}" ); } }