xref: /linux/include/linux/units.h (revision d7c8087a9cd8979d70edfe7c7feda9423feae3ab) !
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 MICROJOULE_PER_JOULE	1000000UL
61 #define NANOJOULE_PER_JOULE	1000000000UL
62 
63 #define BYTES_PER_KBIT		(KILO / BITS_PER_BYTE)
64 #define BYTES_PER_MBIT		(MEGA / BITS_PER_BYTE)
65 #define BYTES_PER_GBIT		(GIGA / BITS_PER_BYTE)
66 
67 #define ABSOLUTE_ZERO_MILLICELSIUS -273150
68 
milli_kelvin_to_millicelsius(long t)69 static inline long milli_kelvin_to_millicelsius(long t)
70 {
71 	return t + ABSOLUTE_ZERO_MILLICELSIUS;
72 }
73 
millicelsius_to_milli_kelvin(long t)74 static inline long millicelsius_to_milli_kelvin(long t)
75 {
76 	return t - ABSOLUTE_ZERO_MILLICELSIUS;
77 }
78 
79 #define MILLIDEGREE_PER_DEGREE 1000
80 #define MILLIDEGREE_PER_DECIDEGREE 100
81 
kelvin_to_millicelsius(long t)82 static inline long kelvin_to_millicelsius(long t)
83 {
84 	return milli_kelvin_to_millicelsius(t * MILLIDEGREE_PER_DEGREE);
85 }
86 
millicelsius_to_kelvin(long t)87 static inline long millicelsius_to_kelvin(long t)
88 {
89 	t = millicelsius_to_milli_kelvin(t);
90 
91 	return DIV_ROUND_CLOSEST(t, MILLIDEGREE_PER_DEGREE);
92 }
93 
deci_kelvin_to_celsius(long t)94 static inline long deci_kelvin_to_celsius(long t)
95 {
96 	t = milli_kelvin_to_millicelsius(t * MILLIDEGREE_PER_DECIDEGREE);
97 
98 	return DIV_ROUND_CLOSEST(t, MILLIDEGREE_PER_DEGREE);
99 }
100 
celsius_to_deci_kelvin(long t)101 static inline long celsius_to_deci_kelvin(long t)
102 {
103 	t = millicelsius_to_milli_kelvin(t * MILLIDEGREE_PER_DEGREE);
104 
105 	return DIV_ROUND_CLOSEST(t, MILLIDEGREE_PER_DECIDEGREE);
106 }
107 
108 /**
109  * deci_kelvin_to_millicelsius_with_offset - convert Kelvin to Celsius
110  * @t: temperature value in decidegrees Kelvin
111  * @offset: difference between Kelvin and Celsius in millidegrees
112  *
113  * Return: temperature value in millidegrees Celsius
114  */
deci_kelvin_to_millicelsius_with_offset(long t,long offset)115 static inline long deci_kelvin_to_millicelsius_with_offset(long t, long offset)
116 {
117 	return t * MILLIDEGREE_PER_DECIDEGREE - offset;
118 }
119 
deci_kelvin_to_millicelsius(long t)120 static inline long deci_kelvin_to_millicelsius(long t)
121 {
122 	return milli_kelvin_to_millicelsius(t * MILLIDEGREE_PER_DECIDEGREE);
123 }
124 
millicelsius_to_deci_kelvin(long t)125 static inline long millicelsius_to_deci_kelvin(long t)
126 {
127 	t = millicelsius_to_milli_kelvin(t);
128 
129 	return DIV_ROUND_CLOSEST(t, MILLIDEGREE_PER_DECIDEGREE);
130 }
131 
kelvin_to_celsius(long t)132 static inline long kelvin_to_celsius(long t)
133 {
134 	return t + DIV_ROUND_CLOSEST(ABSOLUTE_ZERO_MILLICELSIUS,
135 				     MILLIDEGREE_PER_DEGREE);
136 }
137 
celsius_to_kelvin(long t)138 static inline long celsius_to_kelvin(long t)
139 {
140 	return t - DIV_ROUND_CLOSEST(ABSOLUTE_ZERO_MILLICELSIUS,
141 				     MILLIDEGREE_PER_DEGREE);
142 }
143 
144 #endif /* _LINUX_UNITS_H */
145