temperature_convert/
lib.rs1#![no_std]
2cfg_if! {
3 if #[cfg(feature = "std")] {
4 extern crate std;
5 } else {
6 use num_traits::real::Real;
7 }
8}
9use cfg_if::cfg_if;
10
11#[must_use]
12pub const fn kelvin_to_celsius(val: f64) -> f64 {
13 val - 273.15
14}
15
16#[must_use]
17pub fn kelvin_to_fahrenheit(val: f64) -> f64 {
18 cfg_if! {
19 if #[cfg(feature = "std")] {
20 f64::mul_add(val - 273.15, 9. / 5., 32.)
21 } else {
22 Real::mul_add(val - 273.15, 9. / 5., 32.)
23 }
24 }
25}
26
27#[must_use]
28pub const fn celsius_to_kelvin(val: f64) -> f64 {
29 val + 273.15
30}
31
32#[must_use]
33pub fn celsius_to_fahrenheit(val: f64) -> f64 {
34 cfg_if! {
35 if #[cfg(feature = "std")] {
36 f64::mul_add(val, 9. / 5., 32.)
37 } else {
38 Real::mul_add(val, 9. / 5., 32.)
39 }
40 }
41}
42
43#[must_use]
44pub fn fahrenheit_to_kelvin(val: f64) -> f64 {
45 cfg_if! {
46 if #[cfg(feature = "std")] {
47 f64::mul_add(val - 32., 5. / 9., 273.15)
48 } else {
49 Real::mul_add(val - 32., 5. / 9., 273.15)
50 }
51 }
52}
53
54#[must_use]
55pub const fn fahrenheit_to_celsius(val: f64) -> f64 {
56 (val - 32.) * (5. / 9.)
57}
58
59#[cfg(test)]
60mod temperature_tests {
61 use super::*;
62 use rstest::rstest;
63
64 const PRECISION: f64 = f64::EPSILON;
65
66 fn approx_equal(x: f64, y: f64) -> bool {
68 (x - y).abs() < PRECISION
69 }
70
71 #[rstest]
72 #[case(0.0, -273.15)]
73 #[case(100.0, -173.14999999999998)]
74 #[case(1000.0, 726.85)]
75 #[case(5000.0, 4726.85)]
76 fn test_kelvin_to_celsius_precision(#[case] kelvin_val: f64, #[case] celsius_val: f64) {
77 let converted = kelvin_to_celsius(kelvin_val);
78 assert!(
79 approx_equal(converted, celsius_val),
80 "High precision K->C failed - Expected: {celsius_val}, Got: {converted}"
81 );
82 }
83
84 #[rstest]
85 #[case(0.0, -459.66999999999996)]
86 #[case(100.0, -279.66999999999996)]
87 #[case(1000.0, 1340.3300000000002)]
88 #[case(5000.0, 8540.330000000002)]
89 #[case(69420.0, 124496.33000000002)]
90 fn test_kelvin_to_fahrenheit_precision(#[case] kelvin_val: f64, #[case] fahrenheit_val: f64) {
91 let converted = kelvin_to_fahrenheit(kelvin_val);
92 assert!(
93 approx_equal(converted, fahrenheit_val),
94 "High precision K->F failed - Expected: {fahrenheit_val}, Got: {converted}"
95 );
96 }
97
98 #[rstest]
99 #[case(0.0, 273.15)]
100 #[case(100.0, 373.15)]
101 #[case(1000.0, 1273.15)]
102 #[case(5000.0, 5273.15)]
103 #[case(69420.0, 69693.15)]
104 fn test_celsius_to_kelvin_precision(#[case] celsius_val: f64, #[case] kelvin_val: f64) {
105 let converted = celsius_to_kelvin(celsius_val);
106 assert!(
107 approx_equal(converted, kelvin_val),
108 "High precision C->K failed - Expected: {kelvin_val}, Got: {converted}"
109 );
110 }
111
112 #[rstest]
113 #[case(0.0, 32.0)]
114 #[case(100.0, 212.0)]
115 #[case(1000.0, 1832.0)]
116 #[case(5000.0, 9032.0)]
117 #[case(69420.0, 124988.0)]
118 fn test_celsius_to_fahrenheit_precision(#[case] celsius_val: f64, #[case] fahrenheit_val: f64) {
119 let converted = celsius_to_fahrenheit(celsius_val);
120 assert!(
121 approx_equal(converted, fahrenheit_val),
122 "High precision C->F failed - Expected: {fahrenheit_val}, Got: {converted}"
123 );
124 }
125
126 #[rstest]
127 #[case(0.0, 255.3722222222222)]
128 #[case(100.0, 310.92777777777775)]
129 #[case(1000.0, 810.9277777777778)]
130 #[case(5000.0, 3033.15)]
131 #[case(69420.0, 38822.03888888889)]
132 fn test_fahrenheit_to_kelvin_precision(#[case] fahrenheit_val: f64, #[case] kelvin_val: f64) {
133 let converted = fahrenheit_to_kelvin(fahrenheit_val);
134 assert!(
135 approx_equal(converted, kelvin_val),
136 "High precision F->K failed - Expected: {kelvin_val}, Got: {converted}"
137 );
138 }
139
140 #[rstest]
141 #[case(0.0, -17.77777777777778)]
142 #[case(100.0, 37.77777777777778)]
143 #[case(1000.0, 537.7777777777778)]
144 #[case(5000.0, 2760.0)]
145 #[case(69420.0, 38548.88888888889)]
146 fn test_fahrenheit_to_celsius_precision(#[case] fahrenheit_val: f64, #[case] celsius_val: f64) {
147 let converted = fahrenheit_to_celsius(fahrenheit_val);
148 assert!(
149 approx_equal(converted, celsius_val),
150 "High precision F->C failed - Expected: {celsius_val}, Got: {converted}"
151 );
152 }
153}