xref: /linux/include/linux/units.h (revision 505d195b0f96fd613a51b13dde37aa5ad301eb32)
1 /* SPDX-License-Identifier: GPL-2.0 */
2 #ifndef _LINUX_UNITS_H
3 #define _LINUX_UNITS_H
4 
5 #include <linux/bits.h>
6 #include <linux/math.h>
7 
8 /* Metric prefixes in accordance with Système international (d'unités) */
9 #define PETA	1000000000000000ULL
10 #define TERA	1000000000000ULL
11 #define GIGA	1000000000UL
12 #define MEGA	1000000UL
13 #define KILO	1000UL
14 #define HECTO	100UL
15 #define DECA	10UL
16 #define DECI	10UL
17 #define CENTI	100UL
18 #define MILLI	1000UL
19 #define MICRO	1000000UL
20 #define NANO	1000000000UL
21 #define PICO	1000000000000ULL
22 #define FEMTO	1000000000000000ULL
23 
24 /*
25  * Percentage and related scaling units
26  *
27  * These macros define scaling factors used to convert between ratio and
28  * percentage-based representations with different decimal resolutions.
29  * They are used for precise fractional calculations in engineering, finance,
30  * and measurement applications.
31  *
32  * Examples:
33  *   1%     = 0.01    = 1 / PERCENT
34  *   0.1%   = 0.001   = 1 / PERMILLE
35  *   0.01%  = 0.0001  = 1 / PERMYRIAD (1 basis point)
36  *   0.001% = 0.00001 = 1 / PERCENTMILLE
37  */
38 #define PERCENT		100
39 #define PERMILLE	1000
40 #define PERMYRIAD	10000
41 #define PERCENTMILLE	100000
42 
43 #define NANOHZ_PER_HZ		1000000000UL
44 #define MICROHZ_PER_HZ		1000000UL
45 #define MILLIHZ_PER_HZ		1000UL
46 
47 /* Hz based multipliers */
48 #define HZ_PER_KHZ		1000UL
49 #define HZ_PER_MHZ		1000000UL
50 #define HZ_PER_GHZ		1000000000UL
51 
52 /* kHz based multipliers */
53 #define KHZ_PER_MHZ		1000UL
54 #define KHZ_PER_GHZ		1000000UL
55 
56 #define MILLIWATT_PER_WATT	1000UL
57 #define MICROWATT_PER_MILLIWATT	1000UL
58 #define MICROWATT_PER_WATT	1000000UL
59 
60 #define BYTES_PER_KBIT		(KILO / BITS_PER_BYTE)
61 #define BYTES_PER_MBIT		(MEGA / BITS_PER_BYTE)
62 #define BYTES_PER_GBIT		(GIGA / BITS_PER_BYTE)
63 
64 #define ABSOLUTE_ZERO_MILLICELSIUS -273150
65 
66 static inline long milli_kelvin_to_millicelsius(long t)
67 {
68 	return t + ABSOLUTE_ZERO_MILLICELSIUS;
69 }
70 
71 static inline long millicelsius_to_milli_kelvin(long t)
72 {
73 	return t - ABSOLUTE_ZERO_MILLICELSIUS;
74 }
75 
76 #define MILLIDEGREE_PER_DEGREE 1000
77 #define MILLIDEGREE_PER_DECIDEGREE 100
78 
79 static inline long kelvin_to_millicelsius(long t)
80 {
81 	return milli_kelvin_to_millicelsius(t * MILLIDEGREE_PER_DEGREE);
82 }
83 
84 static inline long millicelsius_to_kelvin(long t)
85 {
86 	t = millicelsius_to_milli_kelvin(t);
87 
88 	return DIV_ROUND_CLOSEST(t, MILLIDEGREE_PER_DEGREE);
89 }
90 
91 static inline long deci_kelvin_to_celsius(long t)
92 {
93 	t = milli_kelvin_to_millicelsius(t * MILLIDEGREE_PER_DECIDEGREE);
94 
95 	return DIV_ROUND_CLOSEST(t, MILLIDEGREE_PER_DEGREE);
96 }
97 
98 static inline long celsius_to_deci_kelvin(long t)
99 {
100 	t = millicelsius_to_milli_kelvin(t * MILLIDEGREE_PER_DEGREE);
101 
102 	return DIV_ROUND_CLOSEST(t, MILLIDEGREE_PER_DECIDEGREE);
103 }
104 
105 /**
106  * deci_kelvin_to_millicelsius_with_offset - convert Kelvin to Celsius
107  * @t: temperature value in decidegrees Kelvin
108  * @offset: difference between Kelvin and Celsius in millidegrees
109  *
110  * Return: temperature value in millidegrees Celsius
111  */
112 static inline long deci_kelvin_to_millicelsius_with_offset(long t, long offset)
113 {
114 	return t * MILLIDEGREE_PER_DECIDEGREE - offset;
115 }
116 
117 static inline long deci_kelvin_to_millicelsius(long t)
118 {
119 	return milli_kelvin_to_millicelsius(t * MILLIDEGREE_PER_DECIDEGREE);
120 }
121 
122 static inline long millicelsius_to_deci_kelvin(long t)
123 {
124 	t = millicelsius_to_milli_kelvin(t);
125 
126 	return DIV_ROUND_CLOSEST(t, MILLIDEGREE_PER_DECIDEGREE);
127 }
128 
129 static inline long kelvin_to_celsius(long t)
130 {
131 	return t + DIV_ROUND_CLOSEST(ABSOLUTE_ZERO_MILLICELSIUS,
132 				     MILLIDEGREE_PER_DEGREE);
133 }
134 
135 static inline long celsius_to_kelvin(long t)
136 {
137 	return t - DIV_ROUND_CLOSEST(ABSOLUTE_ZERO_MILLICELSIUS,
138 				     MILLIDEGREE_PER_DEGREE);
139 }
140 
141 #endif /* _LINUX_UNITS_H */
142