1#[inline]
2fn p2d(e: i32) -> f64 {
3 f64::from_bits(((0x3ff + e) as u64) << 52)
4}
5
6#[inline]
7fn p2f(e: i32) -> f32 {
8 f32::from_bits(((0x7f + e) as u32) << 23)
9}
10
11#[no_mangle]
12pub extern "C" fn fabs(x: f64) -> f64 {
13 f64::from_bits(x.to_bits() & ((-1i64 as u64) / 2))
14}
15
16#[no_mangle]
17pub extern "C" fn fabsf(x: f32) -> f32 {
18 f32::from_bits(x.to_bits() & 0x7fffffff)
19}
20
21#[no_mangle]
22pub extern "C" fn copysign(x: f64, y: f64) -> f64 {
23 let mut ux = x.to_bits();
24 ux &= (-1i64 as u64) / 2;
25 ux |= y.to_bits() & (1u64 << 63);
26 f64::from_bits(ux)
27}
28
29#[no_mangle]
30pub extern "C" fn copysignf(x: f32, y: f32) -> f32 {
31 let mut ux = x.to_bits();
32 ux &= 0x7fffffff;
33 ux |= y.to_bits() & 0x80000000;
34 f32::from_bits(ux)
35}
36
37#[no_mangle]
38pub extern "C" fn trunc(x: f64) -> f64 {
39 let ix = x.to_bits();
40 let mut e = ((ix >> 52) & 0x7ff) as i32 - 0x3ff + 12;
41
42 if e >= 52 + 12 {
43 return x;
44 }
45 if e < 12 {
46 e = 1;
47 }
48 let m = (-1i64 as u64) >> e;
49 if (ix & m) == 0 {
50 return x;
51 }
52 force_eval(x + p2d(120));
53 f64::from_bits(ix & !m)
54}
55
56#[no_mangle]
57pub extern "C" fn truncf(x: f32) -> f32 {
58 let ix = x.to_bits();
59 let mut e = ((ix >> 23) & 0xff) as i32 - 0x7f + 9;
60
61 if e >= 23 + 9 {
62 return x;
63 }
64 if e < 9 {
65 e = 1;
66 }
67 let m = (-1i32 as u32) >> e;
68 if (ix & m) == 0 {
69 return x;
70 }
71 force_eval(x + p2f(120));
72 f32::from_bits(ix & !m)
73}
74
75#[no_mangle]
76pub extern "C" fn floor(x: f64) -> f64 {
77 let ix = x.to_bits();
78 let e = ((ix >> 52) & 0x7ff) as i32;
79
80 if e >= 0x3ff + 52 || x == 0.0 {
81 return x;
82 }
83 let y = if ix >> 63 != 0 {
84 x - p2d(52) + p2d(52) - x
85 } else {
86 x + p2d(52) - p2d(52) - x
87 };
88 if e <= 0x3ff - 1 {
89 force_eval(y);
90 return if ix >> 63 != 0 { -1.0 } else { 0.0 };
91 }
92 if y > 0.0 {
93 x + y - 1.0
94 } else {
95 x + y
96 }
97}
98
99#[no_mangle]
100pub extern "C" fn floorf(x: f32) -> f32 {
101 let mut ix = x.to_bits();
102 let e = ((ix >> 23) & 0xff) as i32 - 0x7f;
103
104 if e >= 23 {
105 return x;
106 }
107 if e >= 0 {
108 let m = 0x007fffff >> e;
109 if (ix & m) == 0 {
110 return x;
111 }
112 force_eval(x + p2f(120));
113 if ix >> 31 != 0 {
114 ix += m;
115 }
116 ix &= !m;
117 } else {
118 force_eval(x + p2f(120));
119 if ix >> 31 == 0 {
120 ix = 0;
121 } else if ix << 1 != 0 {
122 return -1.0f32;
123 }
124 }
125 f32::from_bits(ix)
126}
127
128#[no_mangle]
129pub extern "C" fn ceil(x: f64) -> f64 {
130 let ix = x.to_bits();
131 let e = ((ix >> 52) & 0x7ff) as i32;
132
133 if e >= 0x3ff + 52 || x == 0.0 {
134 return x;
135 }
136 let y = if ix >> 63 != 0 {
137 x - p2d(52) + p2d(52) - x
138 } else {
139 x + p2d(52) - p2d(52) - x
140 };
141 if e <= 0x3ff - 1 {
142 force_eval(y);
143 return if ix >> 63 != 0 { -0.0 } else { 1.0 };
144 }
145 if y < 0.0 {
146 x + y + 1.0
147 } else {
148 x + y
149 }
150}
151
152#[no_mangle]
153pub extern "C" fn ceilf(x: f32) -> f32 {
154 let mut ix = x.to_bits();
155 let e = ((ix >> 23) & 0xff) as i32 - 0x7f;
156
157 if e >= 23 {
158 return x;
159 }
160 if e >= 0 {
161 let m = 0x007fffff >> e;
162 if (ix & m) == 0 {
163 return x;
164 }
165 force_eval(x + p2f(120));
166 if ix >> 31 == 0 {
167 ix += m;
168 }
169 ix &= !m;
170 } else {
171 force_eval(x + p2f(120));
172 if ix >> 31 != 0 {
173 return -0.0f32;
174 } else if ix << 1 != 0 {
175 return 1.0f32;
176 }
177 }
178 f32::from_bits(ix)
179}
180
181#[no_mangle]
182pub extern "C" fn round(x: f64) -> f64 {
183 let ix = x.to_bits();
184 let e = ((ix >> 52) & 0x7ff) as i32;
185 let mut ax = x;
186
187 if e >= 0x3ff + 52 {
188 return x;
189 }
190 let neg = ix >> 63 != 0;
191 if neg {
192 ax = -ax;
193 }
194 if e < 0x3ff - 1 {
195 force_eval(ax + p2d(52));
196 return 0.0 * x;
197 }
198 let y = ax + p2d(52) - p2d(52) - ax;
199 let y = if y > 0.5 {
200 y + ax - 1.0
201 } else if y <= -0.5 {
202 y + ax + 1.0
203 } else {
204 y + ax
205 };
206 if neg { -y } else { y }
207}
208
209#[no_mangle]
210pub extern "C" fn roundf(x: f32) -> f32 {
211 let ix = x.to_bits();
212 let e = ((ix >> 23) & 0xff) as i32;
213 let mut ax = x;
214
215 if e >= 0x7f + 23 {
216 return x;
217 }
218 let neg = ix >> 31 != 0;
219 if neg {
220 ax = -ax;
221 }
222 if e < 0x7f - 1 {
223 force_eval(ax + p2f(23));
224 return 0.0f32 * x;
225 }
226 let y = ax + p2f(23) - p2f(23) - ax;
227 let y = if y > 0.5f32 {
228 y + ax - 1.0f32
229 } else if y <= -0.5f32 {
230 y + ax + 1.0f32
231 } else {
232 y + ax
233 };
234 if neg { -y } else { y }
235}
236
237#[no_mangle]
238pub extern "C" fn scalbn(x: f64, n: c_int) -> f64 {
239 let mut y = x;
240 let mut n = n;
241
242 if n > 1023 {
243 y *= p2d(1023);
244 n -= 1023;
245 if n > 1023 {
246 y *= p2d(1023);
247 n -= 1023;
248 if n > 1023 {
249 n = 1023;
250 }
251 }
252 } else if n < -1022 {
253 y *= p2d(-1022) * p2d(53);
254 n += 1022 - 53;
255 if n < -1022 {
256 y *= p2d(-1022) * p2d(53);
257 n += 1022 - 53;
258 if n < -1022 {
259 n = -1022;
260 }
261 }
262 }
263 f64::from_bits(((0x3ff + n) as u64) << 52) * y
264}
265
266#[no_mangle]
267pub extern "C" fn scalbnf(x: f32, n: c_int) -> f32 {
268 let mut y = x;
269 let mut n = n;
270
271 if n > 127 {
272 y *= p2f(127);
273 n -= 127;
274 if n > 127 {
275 y *= p2f(127);
276 n -= 127;
277 if n > 127 {
278 n = 127;
279 }
280 }
281 } else if n < -126 {
282 y *= p2f(-126) * p2f(24);
283 n += 126 - 24;
284 if n < -126 {
285 y *= p2f(-126) * p2f(24);
286 n += 126 - 24;
287 if n < -126 {
288 n = -126;
289 }
290 }
291 }
292 f32::from_bits(((0x7f + n) as u32) << 23) * y
293}
294
295#[no_mangle]
296pub extern "C" fn scalbln(x: f64, n: c_long) -> f64 {
297 let n = if n > c_int::MAX as c_long {
298 c_int::MAX
299 } else if n < c_int::MIN as c_long {
300 c_int::MIN
301 } else {
302 n as c_int
303 };
304 scalbn(x, n)
305}
306
307#[no_mangle]
308pub extern "C" fn scalblnf(x: f32, n: c_long) -> f32 {
309 let n = if n > c_int::MAX as c_long {
310 c_int::MAX
311 } else if n < c_int::MIN as c_long {
312 c_int::MIN
313 } else {
314 n as c_int
315 };
316 scalbnf(x, n)
317}
318
319#[no_mangle]
320pub extern "C" fn ldexp(x: f64, n: c_int) -> f64 {
321 scalbn(x, n)
322}
323
324#[no_mangle]
325pub extern "C" fn ldexpf(x: f32, n: c_int) -> f32 {
326 scalbnf(x, n)
327}
328
329#[no_mangle]
330pub unsafe extern "C" fn frexp(x: f64, e: *mut c_int) -> f64 {
331 let mut ix = x.to_bits();
332 let ee = ((ix >> 52) & 0x7ff) as i32;
333
334 if ee == 0 {
335 if x != 0.0 {
336 let r = frexp(x * p2d(64), e);
337 if !e.is_null() {
338 *e -= 64;
339 }
340 return r;
341 }
342 if !e.is_null() {
343 *e = 0;
344 }
345 return x;
346 }
347 if ee == 0x7ff {
348 if !e.is_null() {
349 *e = 0;
350 }
351 return x;
352 }
353 if !e.is_null() {
354 *e = ee - 0x3fe;
355 }
356 ix &= 0x800fffffffffffffu64;
357 ix |= 0x3fe0000000000000u64;
358 f64::from_bits(ix)
359}
360
361#[no_mangle]
362pub unsafe extern "C" fn frexpf(x: f32, e: *mut c_int) -> f32 {
363 let mut ix = x.to_bits();
364 let ee = ((ix >> 23) & 0xff) as i32;
365
366 if ee == 0 {
367 if x != 0.0f32 {
368 let r = frexpf(x * p2f(64), e);
369 if !e.is_null() {
370 *e -= 64;
371 }
372 return r;
373 }
374 if !e.is_null() {
375 *e = 0;
376 }
377 return x;
378 }
379 if ee == 0xff {
380 if !e.is_null() {
381 *e = 0;
382 }
383 return x;
384 }
385 if !e.is_null() {
386 *e = ee - 0x7e;
387 }
388 ix &= 0x807fffffu32;
389 ix |= 0x3f000000u32;
390 f32::from_bits(ix)
391}
392
393#[no_mangle]
394pub unsafe extern "C" fn modf(x: f64, iptr: *mut f64) -> f64 {
395 let mut ix = x.to_bits();
396 let e = ((ix >> 52) & 0x7ff) as i32 - 0x3ff;
397
398 if e >= 52 {
399 if !iptr.is_null() {
400 *iptr = x;
401 }
402 if e == 0x400 && (ix << 12) != 0 {
403 return x;
404 }
405 return f64::from_bits(ix & (1u64 << 63));
406 }
407 if e < 0 {
408 if !iptr.is_null() {
409 *iptr = f64::from_bits(ix & (1u64 << 63));
410 }
411 return x;
412 }
413 let mask = (-1i64 as u64) >> 12 >> e;
414 if (ix & mask) == 0 {
415 if !iptr.is_null() {
416 *iptr = x;
417 }
418 return f64::from_bits(ix & (1u64 << 63));
419 }
420 ix &= !mask;
421 let i = f64::from_bits(ix);
422 if !iptr.is_null() {
423 *iptr = i;
424 }
425 x - i
426}
427
428#[no_mangle]
429pub unsafe extern "C" fn modff(x: f32, iptr: *mut f32) -> f32 {
430 let mut ix = x.to_bits();
431 let e = ((ix >> 23) & 0xff) as i32 - 0x7f;
432
433 if e >= 23 {
434 if !iptr.is_null() {
435 *iptr = x;
436 }
437 if e == 0x80 && (ix << 9) != 0 {
438 return x;
439 }
440 return f32::from_bits(ix & 0x80000000u32);
441 }
442 if e < 0 {
443 if !iptr.is_null() {
444 *iptr = f32::from_bits(ix & 0x80000000u32);
445 }
446 return x;
447 }
448 let mask = 0x007fffffu32 >> e;
449 if (ix & mask) == 0 {
450 if !iptr.is_null() {
451 *iptr = x;
452 }
453 return f32::from_bits(ix & 0x80000000u32);
454 }
455 ix &= !mask;
456 let i = f32::from_bits(ix);
457 if !iptr.is_null() {
458 *iptr = i;
459 }
460 x - i
461}