1use hexf::hexf32 as h;
28
29const P: [[f32; 7]; 19] = [
36 [
37 h!("0x1.000002p+0"),
38 h!("-0x1.5554d6p-3"),
39 h!("0x1.32c4a4p-4"),
40 h!("-0x1.5336f2p-5"),
41 0.0,
42 0.0,
43 0.0,
44 ], [
46 h!("0x1.707d7ap-17"),
47 h!("0x1.ffe5ap-1"),
48 h!("0x1.86a284p-10"),
49 h!("-0x1.608874p-3"),
50 h!("0x1.1d36dp-7"),
51 h!("0x1.435f08p-4"),
52 h!("-0x1.2861d6p-5"),
53 ], [
55 h!("0x1.2c296cp-10"),
56 h!("0x1.f9d57p-1"),
57 h!("0x1.b8aab8p-5"),
58 h!("-0x1.30b6a4p-2"),
59 h!("0x1.73af8ap-3"),
60 h!("-0x1.a1564ep-5"),
61 h!("0x1.6908p-8"),
62 ], [
64 h!("-0x1.171628p-6"),
65 h!("0x1.1382e6p+0"),
66 h!("-0x1.f8ac18p-4"),
67 h!("-0x1.c6795cp-4"),
68 h!("0x1.2d2dfep-4"),
69 h!("-0x1.38f626p-6"),
70 h!("0x1.f9d716p-10"),
71 ], [
73 h!("-0x1.29739cp-4"),
74 h!("0x1.43decap+0"),
75 h!("-0x1.91761cp-2"),
76 h!("0x1.82261ap-4"),
77 h!("-0x1.eee226p-7"),
78 h!("0x1.746546p-10"),
79 h!("-0x1.f02e6ap-15"),
80 ], [
82 h!("0x1.6722aep-3"),
83 h!("0x1.d6b2e4p-1"),
84 h!("-0x1.7dbe34p-3"),
85 h!("0x1.c10cbep-6"),
86 h!("-0x1.502cc2p-9"),
87 h!("0x1.1e2eb2p-13"),
88 h!("-0x1.a56434p-19"),
89 ], [
91 h!("0x1.6f7ecp-1"),
92 h!("0x1.05fe1p-1"),
93 h!("-0x1.c290eap-5"),
94 h!("0x1.12d0bep-8"),
95 h!("-0x1.a5b282p-13"),
96 h!("0x1.6d57cp-18"),
97 h!("-0x1.108528p-24"),
98 ], [
100 h!("0x1.5ed2bep+0"),
101 h!("0x1.0d3bp-2"),
102 h!("-0x1.d55ab8p-7"),
103 h!("0x1.20902cp-11"),
104 h!("-0x1.bd0e6ap-17"),
105 h!("0x1.82e9d2p-23"),
106 h!("-0x1.214f5cp-30"),
107 ], [
109 h!("0x1.06cee4p+1"),
110 h!("0x1.0f17c2p-3"),
111 h!("-0x1.da366ep-9"),
112 h!("0x1.24229ap-14"),
113 h!("-0x1.c327d6p-21"),
114 h!("0x1.889372p-28"),
115 h!("-0x1.25be4cp-36"),
116 ], [
118 h!("0x1.5f39aep+1"),
119 h!("0x1.0f8076p-4"),
120 h!("-0x1.db39e6p-11"),
121 h!("0x1.24d726p-17"),
122 h!("-0x1.c44a96p-25"),
123 h!("0x1.899114p-33"),
124 h!("-0x1.26784ap-42"),
125 ], [
127 h!("0x1.b7e21p+1"),
128 h!("0x1.0f9492p-5"),
129 h!("-0x1.db65a6p-13"),
130 h!("0x1.24f0f8p-20"),
131 h!("-0x1.c46c0ep-29"),
132 h!("0x1.89a692p-38"),
133 h!("-0x1.2681d4p-48"),
134 ], [
136 h!("0x1.084d12p+2"),
137 h!("0x1.0f923p-6"),
138 h!("-0x1.db5616p-15"),
139 h!("0x1.24df02p-23"),
140 h!("-0x1.c4422p-33"),
141 h!("0x1.89751cp-43"),
142 h!("-0x1.2653cp-54"),
143 ], [
145 h!("0x1.34afcep+2"),
146 h!("0x1.0f76f6p-7"),
147 h!("-0x1.daf3c8p-17"),
148 h!("0x1.24818cp-26"),
149 h!("-0x1.c37d7ep-37"),
150 h!("0x1.889b7ep-48"),
151 h!("-0x1.258ca6p-60"),
152 ], [
154 h!("0x1.610b6ep+2"),
155 h!("0x1.0f7ad8p-8"),
156 h!("-0x1.db022p-19"),
157 h!("0x1.248fa8p-29"),
158 h!("-0x1.c39c7p-41"),
159 h!("0x1.88bf6p-53"),
160 h!("-0x1.25aeeep-66"),
161 ], [
163 h!("0x1.8d6a98p+2"),
164 h!("0x1.0f6f2ep-9"),
165 h!("-0x1.dad874p-21"),
166 h!("0x1.24689p-32"),
167 h!("-0x1.c34ab6p-45"),
168 h!("0x1.886532p-58"),
169 h!("-0x1.255d5ep-72"),
170 ], [
172 h!("0x1.b9c986p+2"),
173 h!("0x1.0f651cp-10"),
174 h!("-0x1.dab52cp-23"),
175 h!("0x1.2447e4p-35"),
176 h!("-0x1.c3079ep-49"),
177 h!("0x1.881ca6p-63"),
178 h!("-0x1.251c46p-78"),
179 ], [
181 h!("0x1.e6269ap+2"),
182 h!("0x1.0f62aep-11"),
183 h!("-0x1.daac6ep-25"),
184 h!("0x1.243f9ep-38"),
185 h!("-0x1.c2f63cp-53"),
186 h!("0x1.88096cp-68"),
187 h!("-0x1.250ac6p-84"),
188 ], [
190 h!("0x1.09425p+3"),
191 h!("0x1.0f5c6ap-12"),
192 h!("-0x1.da96ep-27"),
193 h!("0x1.242c12p-41"),
194 h!("-0x1.c2ceccp-57"),
195 h!("0x1.87df72p-73"),
196 h!("-0x1.24e5eep-90"),
197 ], [
199 h!("0x1.1f707ep+3"),
200 h!("0x1.0f5d12p-13"),
201 h!("-0x1.da990ap-29"),
202 h!("0x1.242df2p-44"),
203 h!("-0x1.c2d272p-61"),
204 h!("0x1.87e32ep-78"),
205 h!("-0x1.24e916p-96"),
206 ], ];
208
209pub fn cr_asinhf16(x: f16) -> f16 {
211 let v = f32::from(x);
212 let u = v.to_bits();
213 let au = u & 0x7fffffff;
214
215 if au >= 0x7f800000 {
216 if (u == 0x7f800000) || ((au & 0x7fffff) != 0) {
219 return x + x;
221 }
222 return x; }
224
225 let i = ((au >> 23) as i32) - 124; let mut t = v;
227 let tt = t * t;
228 let mut y;
229 let p;
230 if i <= 0 {
231 if au <= 0x3d38a000 {
236 if au == 0 {
237 return x;
238 }
239 return if au == u {
240 v - h!("0x1p-26")
241 } else {
242 v + h!("0x1p-26")
243 } as f16;
244 }
245 p = P[0];
246 let c5 = f32::mul_add(p[3], tt, p[2]);
247 let mut c1 = f32::mul_add(p[1], tt, p[0]);
248 c1 = f32::mul_add(c5, tt * tt, c1);
249 y = t * c1;
250 } else {
251 const S: [f32; 2] = [1.0, -1.0];
253 t *= S[(u >> 31) as usize];
256 p = P[i as usize];
257 let mut c4 = f32::mul_add(p[5], t, p[4]);
258 let c2 = f32::mul_add(p[3], t, p[2]);
259 let mut c0 = f32::mul_add(p[1], t, p[0]);
260 c4 = f32::mul_add(p[6], tt, c4);
261 c0 = f32::mul_add(c2, tt, c0);
262 y = f32::mul_add(c4, tt * tt, c0);
263
264 match (i, au) {
266 (7, 0x41936000) => {
268 y = h!("0x1.cdbffep+1"); }
270 (10, 0x436cc000) => {
271 y = h!("0x1.8a4002p+2"); }
273 (11, 0x43f10000) => {
274 y = h!("0x1.b7bffap+2"); }
276 (12, 0x44588000) => {
277 y = h!("0x1.dd4004p+2"); }
279 _ => (),
280 }
281
282 y *= S[(u >> 31) as usize]; }
284
285 y as f16
286}
287
288#[cfg(test)]
289mod tests {
290 #[test]
291 fn exhaustive() {
292 for b in 0..=u16::MAX {
293 let x = f16::from_bits(b);
294 let y1 = super::cr_asinhf16(x);
295 let y2 = core_math::asinhf16(x);
296 assert_eq!(
297 y1.to_bits(),
298 y2.to_bits(),
299 "asinhf16({x} @ {b:#04x}) = ({y1} @ {y1b:#04x}) vs ({y2} @ {y2b:#04x})",
300 y1b = y1.to_bits(),
301 y2b = y2.to_bits()
302 );
303 }
304 }
305
306 #[test]
307 fn edge() {
308 assert_eq!(
309 super::cr_asinhf16(-f16::NAN).to_bits(),
310 (-f16::NAN).to_bits()
311 );
312 assert_eq!(super::cr_asinhf16(-f16::INFINITY), -f16::INFINITY);
313 assert_eq!(super::cr_asinhf16(-0.0).to_bits(), (-0.0_f16).to_bits());
314 assert_eq!(super::cr_asinhf16(0.0).to_bits(), (0.0_f16).to_bits());
315 assert_eq!(super::cr_asinhf16(f16::INFINITY), f16::INFINITY);
316 assert_eq!(super::cr_asinhf16(f16::NAN).to_bits(), (f16::NAN).to_bits());
317 }
318}