std/f128.rs
1//! Constants for the `f128` quadruple-precision floating point type.
2//!
3//! *[See also the `f128` primitive type](primitive@f128).*
4//!
5//! Mathematically significant numbers are provided in the `consts` sub-module.
6
7#[unstable(feature = "f128", issue = "116909")]
8pub use core::f128::consts;
9
10#[cfg(not(test))]
11use crate::intrinsics;
12#[cfg(not(test))]
13use crate::sys::cmath;
14
15#[cfg(not(test))]
16impl f128 {
17 /// Raises a number to a floating point power.
18 ///
19 /// # Unspecified precision
20 ///
21 /// The precision of this function is non-deterministic. This means it varies by platform,
22 /// Rust version, and can even differ within the same execution from one invocation to the next.
23 ///
24 /// # Examples
25 ///
26 /// ```
27 /// #![feature(f128)]
28 /// # #![feature(cfg_target_has_reliable_f16_f128)]
29 /// # #![expect(internal_features)]
30 /// # #[cfg(not(miri))]
31 /// # #[cfg(target_has_reliable_f128_math)] {
32 ///
33 /// let x = 2.0_f128;
34 /// let abs_difference = (x.powf(2.0) - (x * x)).abs();
35 /// assert!(abs_difference <= f128::EPSILON);
36 ///
37 /// assert_eq!(f128::powf(1.0, f128::NAN), 1.0);
38 /// assert_eq!(f128::powf(f128::NAN, 0.0), 1.0);
39 /// # }
40 /// ```
41 #[inline]
42 #[rustc_allow_incoherent_impl]
43 #[unstable(feature = "f128", issue = "116909")]
44 #[must_use = "method returns a new number and does not mutate the original value"]
45 pub fn powf(self, n: f128) -> f128 {
46 unsafe { intrinsics::powf128(self, n) }
47 }
48
49 /// Returns `e^(self)`, (the exponential function).
50 ///
51 /// # Unspecified precision
52 ///
53 /// The precision of this function is non-deterministic. This means it varies by platform,
54 /// Rust version, and can even differ within the same execution from one invocation to the next.
55 ///
56 /// # Examples
57 ///
58 /// ```
59 /// #![feature(f128)]
60 /// # #![feature(cfg_target_has_reliable_f16_f128)]
61 /// # #![expect(internal_features)]
62 /// # #[cfg(not(miri))]
63 /// # #[cfg(target_has_reliable_f128_math)] {
64 ///
65 /// let one = 1.0f128;
66 /// // e^1
67 /// let e = one.exp();
68 ///
69 /// // ln(e) - 1 == 0
70 /// let abs_difference = (e.ln() - 1.0).abs();
71 ///
72 /// assert!(abs_difference <= f128::EPSILON);
73 /// # }
74 /// ```
75 #[inline]
76 #[rustc_allow_incoherent_impl]
77 #[unstable(feature = "f128", issue = "116909")]
78 #[must_use = "method returns a new number and does not mutate the original value"]
79 pub fn exp(self) -> f128 {
80 unsafe { intrinsics::expf128(self) }
81 }
82
83 /// Returns `2^(self)`.
84 ///
85 /// # Unspecified precision
86 ///
87 /// The precision of this function is non-deterministic. This means it varies by platform,
88 /// Rust version, and can even differ within the same execution from one invocation to the next.
89 ///
90 /// # Examples
91 ///
92 /// ```
93 /// #![feature(f128)]
94 /// # #![feature(cfg_target_has_reliable_f16_f128)]
95 /// # #![expect(internal_features)]
96 /// # #[cfg(not(miri))]
97 /// # #[cfg(target_has_reliable_f128_math)] {
98 ///
99 /// let f = 2.0f128;
100 ///
101 /// // 2^2 - 4 == 0
102 /// let abs_difference = (f.exp2() - 4.0).abs();
103 ///
104 /// assert!(abs_difference <= f128::EPSILON);
105 /// # }
106 /// ```
107 #[inline]
108 #[rustc_allow_incoherent_impl]
109 #[unstable(feature = "f128", issue = "116909")]
110 #[must_use = "method returns a new number and does not mutate the original value"]
111 pub fn exp2(self) -> f128 {
112 unsafe { intrinsics::exp2f128(self) }
113 }
114
115 /// Returns the natural logarithm of the number.
116 ///
117 /// This returns NaN when the number is negative, and negative infinity when number is zero.
118 ///
119 /// # Unspecified precision
120 ///
121 /// The precision of this function is non-deterministic. This means it varies by platform,
122 /// Rust version, and can even differ within the same execution from one invocation to the next.
123 ///
124 /// # Examples
125 ///
126 /// ```
127 /// #![feature(f128)]
128 /// # #![feature(cfg_target_has_reliable_f16_f128)]
129 /// # #![expect(internal_features)]
130 /// # #[cfg(not(miri))]
131 /// # #[cfg(target_has_reliable_f128_math)] {
132 ///
133 /// let one = 1.0f128;
134 /// // e^1
135 /// let e = one.exp();
136 ///
137 /// // ln(e) - 1 == 0
138 /// let abs_difference = (e.ln() - 1.0).abs();
139 ///
140 /// assert!(abs_difference <= f128::EPSILON);
141 /// # }
142 /// ```
143 ///
144 /// Non-positive values:
145 /// ```
146 /// #![feature(f128)]
147 /// # #![feature(cfg_target_has_reliable_f16_f128)]
148 /// # #![expect(internal_features)]
149 /// # #[cfg(not(miri))]
150 /// # #[cfg(target_has_reliable_f128_math)] {
151 ///
152 /// assert_eq!(0_f128.ln(), f128::NEG_INFINITY);
153 /// assert!((-42_f128).ln().is_nan());
154 /// # }
155 /// ```
156 #[inline]
157 #[rustc_allow_incoherent_impl]
158 #[unstable(feature = "f128", issue = "116909")]
159 #[must_use = "method returns a new number and does not mutate the original value"]
160 pub fn ln(self) -> f128 {
161 unsafe { intrinsics::logf128(self) }
162 }
163
164 /// Returns the logarithm of the number with respect to an arbitrary base.
165 ///
166 /// This returns NaN when the number is negative, and negative infinity when number is zero.
167 ///
168 /// The result might not be correctly rounded owing to implementation details;
169 /// `self.log2()` can produce more accurate results for base 2, and
170 /// `self.log10()` can produce more accurate results for base 10.
171 ///
172 /// # Unspecified precision
173 ///
174 /// The precision of this function is non-deterministic. This means it varies by platform,
175 /// Rust version, and can even differ within the same execution from one invocation to the next.
176 ///
177 /// # Examples
178 ///
179 /// ```
180 /// #![feature(f128)]
181 /// # #![feature(cfg_target_has_reliable_f16_f128)]
182 /// # #![expect(internal_features)]
183 /// # #[cfg(not(miri))]
184 /// # #[cfg(target_has_reliable_f128_math)] {
185 ///
186 /// let five = 5.0f128;
187 ///
188 /// // log5(5) - 1 == 0
189 /// let abs_difference = (five.log(5.0) - 1.0).abs();
190 ///
191 /// assert!(abs_difference <= f128::EPSILON);
192 /// # }
193 /// ```
194 ///
195 /// Non-positive values:
196 /// ```
197 /// #![feature(f128)]
198 /// # #![feature(cfg_target_has_reliable_f16_f128)]
199 /// # #![expect(internal_features)]
200 /// # #[cfg(not(miri))]
201 /// # #[cfg(target_has_reliable_f128_math)] {
202 ///
203 /// assert_eq!(0_f128.log(10.0), f128::NEG_INFINITY);
204 /// assert!((-42_f128).log(10.0).is_nan());
205 /// # }
206 /// ```
207 #[inline]
208 #[rustc_allow_incoherent_impl]
209 #[unstable(feature = "f128", issue = "116909")]
210 #[must_use = "method returns a new number and does not mutate the original value"]
211 pub fn log(self, base: f128) -> f128 {
212 self.ln() / base.ln()
213 }
214
215 /// Returns the base 2 logarithm of the number.
216 ///
217 /// This returns NaN when the number is negative, and negative infinity when number is zero.
218 ///
219 /// # Unspecified precision
220 ///
221 /// The precision of this function is non-deterministic. This means it varies by platform,
222 /// Rust version, and can even differ within the same execution from one invocation to the next.
223 ///
224 /// # Examples
225 ///
226 /// ```
227 /// #![feature(f128)]
228 /// # #![feature(cfg_target_has_reliable_f16_f128)]
229 /// # #![expect(internal_features)]
230 /// # #[cfg(not(miri))]
231 /// # #[cfg(target_has_reliable_f128_math)] {
232 ///
233 /// let two = 2.0f128;
234 ///
235 /// // log2(2) - 1 == 0
236 /// let abs_difference = (two.log2() - 1.0).abs();
237 ///
238 /// assert!(abs_difference <= f128::EPSILON);
239 /// # }
240 /// ```
241 ///
242 /// Non-positive values:
243 /// ```
244 /// #![feature(f128)]
245 /// # #![feature(cfg_target_has_reliable_f16_f128)]
246 /// # #![expect(internal_features)]
247 /// # #[cfg(not(miri))]
248 /// # #[cfg(target_has_reliable_f128_math)] {
249 ///
250 /// assert_eq!(0_f128.log2(), f128::NEG_INFINITY);
251 /// assert!((-42_f128).log2().is_nan());
252 /// # }
253 /// ```
254 #[inline]
255 #[rustc_allow_incoherent_impl]
256 #[unstable(feature = "f128", issue = "116909")]
257 #[must_use = "method returns a new number and does not mutate the original value"]
258 pub fn log2(self) -> f128 {
259 unsafe { intrinsics::log2f128(self) }
260 }
261
262 /// Returns the base 10 logarithm of the number.
263 ///
264 /// This returns NaN when the number is negative, and negative infinity when number is zero.
265 ///
266 /// # Unspecified precision
267 ///
268 /// The precision of this function is non-deterministic. This means it varies by platform,
269 /// Rust version, and can even differ within the same execution from one invocation to the next.
270 ///
271 /// # Examples
272 ///
273 /// ```
274 /// #![feature(f128)]
275 /// # #![feature(cfg_target_has_reliable_f16_f128)]
276 /// # #![expect(internal_features)]
277 /// # #[cfg(not(miri))]
278 /// # #[cfg(target_has_reliable_f128_math)] {
279 ///
280 /// let ten = 10.0f128;
281 ///
282 /// // log10(10) - 1 == 0
283 /// let abs_difference = (ten.log10() - 1.0).abs();
284 ///
285 /// assert!(abs_difference <= f128::EPSILON);
286 /// # }
287 /// ```
288 ///
289 /// Non-positive values:
290 /// ```
291 /// #![feature(f128)]
292 /// # #![feature(cfg_target_has_reliable_f16_f128)]
293 /// # #![expect(internal_features)]
294 /// # #[cfg(not(miri))]
295 /// # #[cfg(target_has_reliable_f128_math)] {
296 ///
297 /// assert_eq!(0_f128.log10(), f128::NEG_INFINITY);
298 /// assert!((-42_f128).log10().is_nan());
299 /// # }
300 /// ```
301 #[inline]
302 #[rustc_allow_incoherent_impl]
303 #[unstable(feature = "f128", issue = "116909")]
304 #[must_use = "method returns a new number and does not mutate the original value"]
305 pub fn log10(self) -> f128 {
306 unsafe { intrinsics::log10f128(self) }
307 }
308
309 /// Returns the cube root of a number.
310 ///
311 /// # Unspecified precision
312 ///
313 /// The precision of this function is non-deterministic. This means it varies by platform,
314 /// Rust version, and can even differ within the same execution from one invocation to the next.
315 ///
316 ///
317 /// This function currently corresponds to the `cbrtf128` from libc on Unix
318 /// and Windows. Note that this might change in the future.
319 ///
320 /// # Examples
321 ///
322 /// ```
323 /// #![feature(f128)]
324 /// # #![feature(cfg_target_has_reliable_f16_f128)]
325 /// # #![expect(internal_features)]
326 /// # #[cfg(not(miri))]
327 /// # #[cfg(target_has_reliable_f128_math)] {
328 ///
329 /// let x = 8.0f128;
330 ///
331 /// // x^(1/3) - 2 == 0
332 /// let abs_difference = (x.cbrt() - 2.0).abs();
333 ///
334 /// assert!(abs_difference <= f128::EPSILON);
335 /// # }
336 /// ```
337 #[inline]
338 #[rustc_allow_incoherent_impl]
339 #[unstable(feature = "f128", issue = "116909")]
340 #[must_use = "method returns a new number and does not mutate the original value"]
341 pub fn cbrt(self) -> f128 {
342 cmath::cbrtf128(self)
343 }
344
345 /// Compute the distance between the origin and a point (`x`, `y`) on the
346 /// Euclidean plane. Equivalently, compute the length of the hypotenuse of a
347 /// right-angle triangle with other sides having length `x.abs()` and
348 /// `y.abs()`.
349 ///
350 /// # Unspecified precision
351 ///
352 /// The precision of this function is non-deterministic. This means it varies by platform,
353 /// Rust version, and can even differ within the same execution from one invocation to the next.
354 ///
355 ///
356 /// This function currently corresponds to the `hypotf128` from libc on Unix
357 /// and Windows. Note that this might change in the future.
358 ///
359 /// # Examples
360 ///
361 /// ```
362 /// #![feature(f128)]
363 /// # #![feature(cfg_target_has_reliable_f16_f128)]
364 /// # #![expect(internal_features)]
365 /// # #[cfg(not(miri))]
366 /// # #[cfg(target_has_reliable_f128_math)] {
367 ///
368 /// let x = 2.0f128;
369 /// let y = 3.0f128;
370 ///
371 /// // sqrt(x^2 + y^2)
372 /// let abs_difference = (x.hypot(y) - (x.powi(2) + y.powi(2)).sqrt()).abs();
373 ///
374 /// assert!(abs_difference <= f128::EPSILON);
375 /// # }
376 /// ```
377 #[inline]
378 #[rustc_allow_incoherent_impl]
379 #[unstable(feature = "f128", issue = "116909")]
380 #[must_use = "method returns a new number and does not mutate the original value"]
381 pub fn hypot(self, other: f128) -> f128 {
382 cmath::hypotf128(self, other)
383 }
384
385 /// Computes the sine of a number (in radians).
386 ///
387 /// # Unspecified precision
388 ///
389 /// The precision of this function is non-deterministic. This means it varies by platform,
390 /// Rust version, and can even differ within the same execution from one invocation to the next.
391 ///
392 /// # Examples
393 ///
394 /// ```
395 /// #![feature(f128)]
396 /// # #![feature(cfg_target_has_reliable_f16_f128)]
397 /// # #![expect(internal_features)]
398 /// # #[cfg(not(miri))]
399 /// # #[cfg(target_has_reliable_f128_math)] {
400 ///
401 /// let x = std::f128::consts::FRAC_PI_2;
402 ///
403 /// let abs_difference = (x.sin() - 1.0).abs();
404 ///
405 /// assert!(abs_difference <= f128::EPSILON);
406 /// # }
407 /// ```
408 #[inline]
409 #[rustc_allow_incoherent_impl]
410 #[unstable(feature = "f128", issue = "116909")]
411 #[must_use = "method returns a new number and does not mutate the original value"]
412 pub fn sin(self) -> f128 {
413 unsafe { intrinsics::sinf128(self) }
414 }
415
416 /// Computes the cosine of a number (in radians).
417 ///
418 /// # Unspecified precision
419 ///
420 /// The precision of this function is non-deterministic. This means it varies by platform,
421 /// Rust version, and can even differ within the same execution from one invocation to the next.
422 ///
423 /// # Examples
424 ///
425 /// ```
426 /// #![feature(f128)]
427 /// # #![feature(cfg_target_has_reliable_f16_f128)]
428 /// # #![expect(internal_features)]
429 /// # #[cfg(not(miri))]
430 /// # #[cfg(target_has_reliable_f128_math)] {
431 ///
432 /// let x = 2.0 * std::f128::consts::PI;
433 ///
434 /// let abs_difference = (x.cos() - 1.0).abs();
435 ///
436 /// assert!(abs_difference <= f128::EPSILON);
437 /// # }
438 /// ```
439 #[inline]
440 #[rustc_allow_incoherent_impl]
441 #[unstable(feature = "f128", issue = "116909")]
442 #[must_use = "method returns a new number and does not mutate the original value"]
443 pub fn cos(self) -> f128 {
444 unsafe { intrinsics::cosf128(self) }
445 }
446
447 /// Computes the tangent of a number (in radians).
448 ///
449 /// # Unspecified precision
450 ///
451 /// The precision of this function is non-deterministic. This means it varies by platform,
452 /// Rust version, and can even differ within the same execution from one invocation to the next.
453 ///
454 /// This function currently corresponds to the `tanf128` from libc on Unix and
455 /// Windows. Note that this might change in the future.
456 ///
457 /// # Examples
458 ///
459 /// ```
460 /// #![feature(f128)]
461 /// # #![feature(cfg_target_has_reliable_f16_f128)]
462 /// # #![expect(internal_features)]
463 /// # #[cfg(not(miri))]
464 /// # #[cfg(target_has_reliable_f128_math)] {
465 ///
466 /// let x = std::f128::consts::FRAC_PI_4;
467 /// let abs_difference = (x.tan() - 1.0).abs();
468 ///
469 /// assert!(abs_difference <= f128::EPSILON);
470 /// # }
471 /// ```
472 #[inline]
473 #[rustc_allow_incoherent_impl]
474 #[unstable(feature = "f128", issue = "116909")]
475 #[must_use = "method returns a new number and does not mutate the original value"]
476 pub fn tan(self) -> f128 {
477 cmath::tanf128(self)
478 }
479
480 /// Computes the arcsine of a number. Return value is in radians in
481 /// the range [-pi/2, pi/2] or NaN if the number is outside the range
482 /// [-1, 1].
483 ///
484 /// # Unspecified precision
485 ///
486 /// The precision of this function is non-deterministic. This means it varies by platform,
487 /// Rust version, and can even differ within the same execution from one invocation to the next.
488 ///
489 /// This function currently corresponds to the `asinf128` from libc on Unix
490 /// and Windows. Note that this might change in the future.
491 ///
492 /// # Examples
493 ///
494 /// ```
495 /// #![feature(f128)]
496 /// # #![feature(cfg_target_has_reliable_f16_f128)]
497 /// # #![expect(internal_features)]
498 /// # #[cfg(not(miri))]
499 /// # #[cfg(target_has_reliable_f128_math)] {
500 ///
501 /// let f = std::f128::consts::FRAC_PI_2;
502 ///
503 /// // asin(sin(pi/2))
504 /// let abs_difference = (f.sin().asin() - std::f128::consts::FRAC_PI_2).abs();
505 ///
506 /// assert!(abs_difference <= f128::EPSILON);
507 /// # }
508 /// ```
509 #[inline]
510 #[doc(alias = "arcsin")]
511 #[rustc_allow_incoherent_impl]
512 #[unstable(feature = "f128", issue = "116909")]
513 #[must_use = "method returns a new number and does not mutate the original value"]
514 pub fn asin(self) -> f128 {
515 cmath::asinf128(self)
516 }
517
518 /// Computes the arccosine of a number. Return value is in radians in
519 /// the range [0, pi] or NaN if the number is outside the range
520 /// [-1, 1].
521 ///
522 /// # Unspecified precision
523 ///
524 /// The precision of this function is non-deterministic. This means it varies by platform,
525 /// Rust version, and can even differ within the same execution from one invocation to the next.
526 ///
527 /// This function currently corresponds to the `acosf128` from libc on Unix
528 /// and Windows. Note that this might change in the future.
529 ///
530 /// # Examples
531 ///
532 /// ```
533 /// #![feature(f128)]
534 /// # #![feature(cfg_target_has_reliable_f16_f128)]
535 /// # #![expect(internal_features)]
536 /// # #[cfg(not(miri))]
537 /// # #[cfg(target_has_reliable_f128_math)] {
538 ///
539 /// let f = std::f128::consts::FRAC_PI_4;
540 ///
541 /// // acos(cos(pi/4))
542 /// let abs_difference = (f.cos().acos() - std::f128::consts::FRAC_PI_4).abs();
543 ///
544 /// assert!(abs_difference <= f128::EPSILON);
545 /// # }
546 /// ```
547 #[inline]
548 #[doc(alias = "arccos")]
549 #[rustc_allow_incoherent_impl]
550 #[unstable(feature = "f128", issue = "116909")]
551 #[must_use = "method returns a new number and does not mutate the original value"]
552 pub fn acos(self) -> f128 {
553 cmath::acosf128(self)
554 }
555
556 /// Computes the arctangent of a number. Return value is in radians in the
557 /// range [-pi/2, pi/2];
558 ///
559 /// # Unspecified precision
560 ///
561 /// The precision of this function is non-deterministic. This means it varies by platform,
562 /// Rust version, and can even differ within the same execution from one invocation to the next.
563 ///
564 /// This function currently corresponds to the `atanf128` from libc on Unix
565 /// and Windows. Note that this might change in the future.
566 ///
567 /// # Examples
568 ///
569 /// ```
570 /// #![feature(f128)]
571 /// # #![feature(cfg_target_has_reliable_f16_f128)]
572 /// # #![expect(internal_features)]
573 /// # #[cfg(not(miri))]
574 /// # #[cfg(target_has_reliable_f128_math)] {
575 ///
576 /// let f = 1.0f128;
577 ///
578 /// // atan(tan(1))
579 /// let abs_difference = (f.tan().atan() - 1.0).abs();
580 ///
581 /// assert!(abs_difference <= f128::EPSILON);
582 /// # }
583 /// ```
584 #[inline]
585 #[doc(alias = "arctan")]
586 #[rustc_allow_incoherent_impl]
587 #[unstable(feature = "f128", issue = "116909")]
588 #[must_use = "method returns a new number and does not mutate the original value"]
589 pub fn atan(self) -> f128 {
590 cmath::atanf128(self)
591 }
592
593 /// Computes the four quadrant arctangent of `self` (`y`) and `other` (`x`) in radians.
594 ///
595 /// * `x = 0`, `y = 0`: `0`
596 /// * `x >= 0`: `arctan(y/x)` -> `[-pi/2, pi/2]`
597 /// * `y >= 0`: `arctan(y/x) + pi` -> `(pi/2, pi]`
598 /// * `y < 0`: `arctan(y/x) - pi` -> `(-pi, -pi/2)`
599 ///
600 /// # Unspecified precision
601 ///
602 /// The precision of this function is non-deterministic. This means it varies by platform,
603 /// Rust version, and can even differ within the same execution from one invocation to the next.
604 ///
605 /// This function currently corresponds to the `atan2f128` from libc on Unix
606 /// and Windows. Note that this might change in the future.
607 ///
608 /// # Examples
609 ///
610 /// ```
611 /// #![feature(f128)]
612 /// # #![feature(cfg_target_has_reliable_f16_f128)]
613 /// # #![expect(internal_features)]
614 /// # #[cfg(not(miri))]
615 /// # #[cfg(target_has_reliable_f128_math)] {
616 ///
617 /// // Positive angles measured counter-clockwise
618 /// // from positive x axis
619 /// // -pi/4 radians (45 deg clockwise)
620 /// let x1 = 3.0f128;
621 /// let y1 = -3.0f128;
622 ///
623 /// // 3pi/4 radians (135 deg counter-clockwise)
624 /// let x2 = -3.0f128;
625 /// let y2 = 3.0f128;
626 ///
627 /// let abs_difference_1 = (y1.atan2(x1) - (-std::f128::consts::FRAC_PI_4)).abs();
628 /// let abs_difference_2 = (y2.atan2(x2) - (3.0 * std::f128::consts::FRAC_PI_4)).abs();
629 ///
630 /// assert!(abs_difference_1 <= f128::EPSILON);
631 /// assert!(abs_difference_2 <= f128::EPSILON);
632 /// # }
633 /// ```
634 #[inline]
635 #[rustc_allow_incoherent_impl]
636 #[unstable(feature = "f128", issue = "116909")]
637 #[must_use = "method returns a new number and does not mutate the original value"]
638 pub fn atan2(self, other: f128) -> f128 {
639 cmath::atan2f128(self, other)
640 }
641
642 /// Simultaneously computes the sine and cosine of the number, `x`. Returns
643 /// `(sin(x), cos(x))`.
644 ///
645 /// # Unspecified precision
646 ///
647 /// The precision of this function is non-deterministic. This means it varies by platform,
648 /// Rust version, and can even differ within the same execution from one invocation to the next.
649 ///
650 /// This function currently corresponds to the `(f128::sin(x),
651 /// f128::cos(x))`. Note that this might change in the future.
652 ///
653 /// # Examples
654 ///
655 /// ```
656 /// #![feature(f128)]
657 /// # #![feature(cfg_target_has_reliable_f16_f128)]
658 /// # #![expect(internal_features)]
659 /// # #[cfg(not(miri))]
660 /// # #[cfg(target_has_reliable_f128_math)] {
661 ///
662 /// let x = std::f128::consts::FRAC_PI_4;
663 /// let f = x.sin_cos();
664 ///
665 /// let abs_difference_0 = (f.0 - x.sin()).abs();
666 /// let abs_difference_1 = (f.1 - x.cos()).abs();
667 ///
668 /// assert!(abs_difference_0 <= f128::EPSILON);
669 /// assert!(abs_difference_1 <= f128::EPSILON);
670 /// # }
671 /// ```
672 #[inline]
673 #[doc(alias = "sincos")]
674 #[rustc_allow_incoherent_impl]
675 #[unstable(feature = "f128", issue = "116909")]
676 pub fn sin_cos(self) -> (f128, f128) {
677 (self.sin(), self.cos())
678 }
679
680 /// Returns `e^(self) - 1` in a way that is accurate even if the
681 /// number is close to zero.
682 ///
683 /// # Unspecified precision
684 ///
685 /// The precision of this function is non-deterministic. This means it varies by platform,
686 /// Rust version, and can even differ within the same execution from one invocation to the next.
687 ///
688 /// This function currently corresponds to the `expm1f128` from libc on Unix
689 /// and Windows. Note that this might change in the future.
690 ///
691 /// # Examples
692 ///
693 /// ```
694 /// #![feature(f128)]
695 /// # #![feature(cfg_target_has_reliable_f16_f128)]
696 /// # #![expect(internal_features)]
697 /// # #[cfg(not(miri))]
698 /// # #[cfg(target_has_reliable_f128_math)] {
699 ///
700 /// let x = 1e-8_f128;
701 ///
702 /// // for very small x, e^x is approximately 1 + x + x^2 / 2
703 /// let approx = x + x * x / 2.0;
704 /// let abs_difference = (x.exp_m1() - approx).abs();
705 ///
706 /// assert!(abs_difference < 1e-10);
707 /// # }
708 /// ```
709 #[inline]
710 #[rustc_allow_incoherent_impl]
711 #[unstable(feature = "f128", issue = "116909")]
712 #[must_use = "method returns a new number and does not mutate the original value"]
713 pub fn exp_m1(self) -> f128 {
714 cmath::expm1f128(self)
715 }
716
717 /// Returns `ln(1+n)` (natural logarithm) more accurately than if
718 /// the operations were performed separately.
719 ///
720 /// This returns NaN when `n < -1.0`, and negative infinity when `n == -1.0`.
721 ///
722 /// # Unspecified precision
723 ///
724 /// The precision of this function is non-deterministic. This means it varies by platform,
725 /// Rust version, and can even differ within the same execution from one invocation to the next.
726 ///
727 /// This function currently corresponds to the `log1pf128` from libc on Unix
728 /// and Windows. Note that this might change in the future.
729 ///
730 /// # Examples
731 ///
732 /// ```
733 /// #![feature(f128)]
734 /// # #![feature(cfg_target_has_reliable_f16_f128)]
735 /// # #![expect(internal_features)]
736 /// # #[cfg(not(miri))]
737 /// # #[cfg(target_has_reliable_f128_math)] {
738 ///
739 /// let x = 1e-8_f128;
740 ///
741 /// // for very small x, ln(1 + x) is approximately x - x^2 / 2
742 /// let approx = x - x * x / 2.0;
743 /// let abs_difference = (x.ln_1p() - approx).abs();
744 ///
745 /// assert!(abs_difference < 1e-10);
746 /// # }
747 /// ```
748 ///
749 /// Out-of-range values:
750 /// ```
751 /// #![feature(f128)]
752 /// # #![feature(cfg_target_has_reliable_f16_f128)]
753 /// # #![expect(internal_features)]
754 /// # #[cfg(not(miri))]
755 /// # #[cfg(target_has_reliable_f128_math)] {
756 ///
757 /// assert_eq!((-1.0_f128).ln_1p(), f128::NEG_INFINITY);
758 /// assert!((-2.0_f128).ln_1p().is_nan());
759 /// # }
760 /// ```
761 #[inline]
762 #[doc(alias = "log1p")]
763 #[must_use = "method returns a new number and does not mutate the original value"]
764 #[rustc_allow_incoherent_impl]
765 #[unstable(feature = "f128", issue = "116909")]
766 pub fn ln_1p(self) -> f128 {
767 cmath::log1pf128(self)
768 }
769
770 /// Hyperbolic sine function.
771 ///
772 /// # Unspecified precision
773 ///
774 /// The precision of this function is non-deterministic. This means it varies by platform,
775 /// Rust version, and can even differ within the same execution from one invocation to the next.
776 ///
777 /// This function currently corresponds to the `sinhf128` from libc on Unix
778 /// and Windows. Note that this might change in the future.
779 ///
780 /// # Examples
781 ///
782 /// ```
783 /// #![feature(f128)]
784 /// # #![feature(cfg_target_has_reliable_f16_f128)]
785 /// # #![expect(internal_features)]
786 /// # #[cfg(not(miri))]
787 /// # #[cfg(target_has_reliable_f128_math)] {
788 ///
789 /// let e = std::f128::consts::E;
790 /// let x = 1.0f128;
791 ///
792 /// let f = x.sinh();
793 /// // Solving sinh() at 1 gives `(e^2-1)/(2e)`
794 /// let g = ((e * e) - 1.0) / (2.0 * e);
795 /// let abs_difference = (f - g).abs();
796 ///
797 /// assert!(abs_difference <= f128::EPSILON);
798 /// # }
799 /// ```
800 #[inline]
801 #[rustc_allow_incoherent_impl]
802 #[unstable(feature = "f128", issue = "116909")]
803 #[must_use = "method returns a new number and does not mutate the original value"]
804 pub fn sinh(self) -> f128 {
805 cmath::sinhf128(self)
806 }
807
808 /// Hyperbolic cosine function.
809 ///
810 /// # Unspecified precision
811 ///
812 /// The precision of this function is non-deterministic. This means it varies by platform,
813 /// Rust version, and can even differ within the same execution from one invocation to the next.
814 ///
815 /// This function currently corresponds to the `coshf128` from libc on Unix
816 /// and Windows. Note that this might change in the future.
817 ///
818 /// # Examples
819 ///
820 /// ```
821 /// #![feature(f128)]
822 /// # #![feature(cfg_target_has_reliable_f16_f128)]
823 /// # #![expect(internal_features)]
824 /// # #[cfg(not(miri))]
825 /// # #[cfg(target_has_reliable_f128_math)] {
826 ///
827 /// let e = std::f128::consts::E;
828 /// let x = 1.0f128;
829 /// let f = x.cosh();
830 /// // Solving cosh() at 1 gives this result
831 /// let g = ((e * e) + 1.0) / (2.0 * e);
832 /// let abs_difference = (f - g).abs();
833 ///
834 /// // Same result
835 /// assert!(abs_difference <= f128::EPSILON);
836 /// # }
837 /// ```
838 #[inline]
839 #[rustc_allow_incoherent_impl]
840 #[unstable(feature = "f128", issue = "116909")]
841 #[must_use = "method returns a new number and does not mutate the original value"]
842 pub fn cosh(self) -> f128 {
843 cmath::coshf128(self)
844 }
845
846 /// Hyperbolic tangent function.
847 ///
848 /// # Unspecified precision
849 ///
850 /// The precision of this function is non-deterministic. This means it varies by platform,
851 /// Rust version, and can even differ within the same execution from one invocation to the next.
852 ///
853 /// This function currently corresponds to the `tanhf128` from libc on Unix
854 /// and Windows. Note that this might change in the future.
855 ///
856 /// # Examples
857 ///
858 /// ```
859 /// #![feature(f128)]
860 /// # #![feature(cfg_target_has_reliable_f16_f128)]
861 /// # #![expect(internal_features)]
862 /// # #[cfg(not(miri))]
863 /// # #[cfg(target_has_reliable_f128_math)] {
864 ///
865 /// let e = std::f128::consts::E;
866 /// let x = 1.0f128;
867 ///
868 /// let f = x.tanh();
869 /// // Solving tanh() at 1 gives `(1 - e^(-2))/(1 + e^(-2))`
870 /// let g = (1.0 - e.powi(-2)) / (1.0 + e.powi(-2));
871 /// let abs_difference = (f - g).abs();
872 ///
873 /// assert!(abs_difference <= f128::EPSILON);
874 /// # }
875 /// ```
876 #[inline]
877 #[rustc_allow_incoherent_impl]
878 #[unstable(feature = "f128", issue = "116909")]
879 #[must_use = "method returns a new number and does not mutate the original value"]
880 pub fn tanh(self) -> f128 {
881 cmath::tanhf128(self)
882 }
883
884 /// Inverse hyperbolic sine function.
885 ///
886 /// # Unspecified precision
887 ///
888 /// The precision of this function is non-deterministic. This means it varies by platform,
889 /// Rust version, and can even differ within the same execution from one invocation to the next.
890 ///
891 /// # Examples
892 ///
893 /// ```
894 /// #![feature(f128)]
895 /// # #![feature(cfg_target_has_reliable_f16_f128)]
896 /// # #![expect(internal_features)]
897 /// # #[cfg(not(miri))]
898 /// # #[cfg(target_has_reliable_f128_math)] {
899 ///
900 /// let x = 1.0f128;
901 /// let f = x.sinh().asinh();
902 ///
903 /// let abs_difference = (f - x).abs();
904 ///
905 /// assert!(abs_difference <= f128::EPSILON);
906 /// # }
907 /// ```
908 #[inline]
909 #[doc(alias = "arcsinh")]
910 #[rustc_allow_incoherent_impl]
911 #[unstable(feature = "f128", issue = "116909")]
912 #[must_use = "method returns a new number and does not mutate the original value"]
913 pub fn asinh(self) -> f128 {
914 let ax = self.abs();
915 let ix = 1.0 / ax;
916 (ax + (ax / (Self::hypot(1.0, ix) + ix))).ln_1p().copysign(self)
917 }
918
919 /// Inverse hyperbolic cosine function.
920 ///
921 /// # Unspecified precision
922 ///
923 /// The precision of this function is non-deterministic. This means it varies by platform,
924 /// Rust version, and can even differ within the same execution from one invocation to the next.
925 ///
926 /// # Examples
927 ///
928 /// ```
929 /// #![feature(f128)]
930 /// # #![feature(cfg_target_has_reliable_f16_f128)]
931 /// # #![expect(internal_features)]
932 /// # #[cfg(not(miri))]
933 /// # #[cfg(target_has_reliable_f128_math)] {
934 ///
935 /// let x = 1.0f128;
936 /// let f = x.cosh().acosh();
937 ///
938 /// let abs_difference = (f - x).abs();
939 ///
940 /// assert!(abs_difference <= f128::EPSILON);
941 /// # }
942 /// ```
943 #[inline]
944 #[doc(alias = "arccosh")]
945 #[rustc_allow_incoherent_impl]
946 #[unstable(feature = "f128", issue = "116909")]
947 #[must_use = "method returns a new number and does not mutate the original value"]
948 pub fn acosh(self) -> f128 {
949 if self < 1.0 {
950 Self::NAN
951 } else {
952 (self + ((self - 1.0).sqrt() * (self + 1.0).sqrt())).ln()
953 }
954 }
955
956 /// Inverse hyperbolic tangent function.
957 ///
958 /// # Unspecified precision
959 ///
960 /// The precision of this function is non-deterministic. This means it varies by platform,
961 /// Rust version, and can even differ within the same execution from one invocation to the next.
962 ///
963 /// # Examples
964 ///
965 /// ```
966 /// #![feature(f128)]
967 /// # #![feature(cfg_target_has_reliable_f16_f128)]
968 /// # #![expect(internal_features)]
969 /// # #[cfg(not(miri))]
970 /// # #[cfg(target_has_reliable_f128_math)] {
971 ///
972 /// let e = std::f128::consts::E;
973 /// let f = e.tanh().atanh();
974 ///
975 /// let abs_difference = (f - e).abs();
976 ///
977 /// assert!(abs_difference <= 1e-5);
978 /// # }
979 /// ```
980 #[inline]
981 #[doc(alias = "arctanh")]
982 #[rustc_allow_incoherent_impl]
983 #[unstable(feature = "f128", issue = "116909")]
984 #[must_use = "method returns a new number and does not mutate the original value"]
985 pub fn atanh(self) -> f128 {
986 0.5 * ((2.0 * self) / (1.0 - self)).ln_1p()
987 }
988
989 /// Gamma function.
990 ///
991 /// # Unspecified precision
992 ///
993 /// The precision of this function is non-deterministic. This means it varies by platform,
994 /// Rust version, and can even differ within the same execution from one invocation to the next.
995 ///
996 /// This function currently corresponds to the `tgammaf128` from libc on Unix
997 /// and Windows. Note that this might change in the future.
998 ///
999 /// # Examples
1000 ///
1001 /// ```
1002 /// #![feature(f128)]
1003 /// #![feature(float_gamma)]
1004 /// # #![feature(cfg_target_has_reliable_f16_f128)]
1005 /// # #![expect(internal_features)]
1006 /// # #[cfg(not(miri))]
1007 /// # #[cfg(target_has_reliable_f128_math)] {
1008 ///
1009 /// let x = 5.0f128;
1010 ///
1011 /// let abs_difference = (x.gamma() - 24.0).abs();
1012 ///
1013 /// assert!(abs_difference <= f128::EPSILON);
1014 /// # }
1015 /// ```
1016 #[inline]
1017 #[rustc_allow_incoherent_impl]
1018 #[unstable(feature = "f128", issue = "116909")]
1019 // #[unstable(feature = "float_gamma", issue = "99842")]
1020 #[must_use = "method returns a new number and does not mutate the original value"]
1021 pub fn gamma(self) -> f128 {
1022 cmath::tgammaf128(self)
1023 }
1024
1025 /// Natural logarithm of the absolute value of the gamma function
1026 ///
1027 /// The integer part of the tuple indicates the sign of the gamma function.
1028 ///
1029 /// # Unspecified precision
1030 ///
1031 /// The precision of this function is non-deterministic. This means it varies by platform,
1032 /// Rust version, and can even differ within the same execution from one invocation to the next.
1033 ///
1034 /// This function currently corresponds to the `lgammaf128_r` from libc on Unix
1035 /// and Windows. Note that this might change in the future.
1036 ///
1037 /// # Examples
1038 ///
1039 /// ```
1040 /// #![feature(f128)]
1041 /// #![feature(float_gamma)]
1042 /// # #![feature(cfg_target_has_reliable_f16_f128)]
1043 /// # #![expect(internal_features)]
1044 /// # #[cfg(not(miri))]
1045 /// # #[cfg(target_has_reliable_f128_math)] {
1046 ///
1047 /// let x = 2.0f128;
1048 ///
1049 /// let abs_difference = (x.ln_gamma().0 - 0.0).abs();
1050 ///
1051 /// assert!(abs_difference <= f128::EPSILON);
1052 /// # }
1053 /// ```
1054 #[inline]
1055 #[rustc_allow_incoherent_impl]
1056 #[unstable(feature = "f128", issue = "116909")]
1057 // #[unstable(feature = "float_gamma", issue = "99842")]
1058 #[must_use = "method returns a new number and does not mutate the original value"]
1059 pub fn ln_gamma(self) -> (f128, i32) {
1060 let mut signgamp: i32 = 0;
1061 let x = cmath::lgammaf128_r(self, &mut signgamp);
1062 (x, signgamp)
1063 }
1064
1065 /// Error function.
1066 ///
1067 /// # Unspecified precision
1068 ///
1069 /// The precision of this function is non-deterministic. This means it varies by platform,
1070 /// Rust version, and can even differ within the same execution from one invocation to the next.
1071 ///
1072 /// This function currently corresponds to the `erff128` from libc on Unix
1073 /// and Windows. Note that this might change in the future.
1074 ///
1075 /// # Examples
1076 ///
1077 /// ```
1078 /// #![feature(f128)]
1079 /// #![feature(float_erf)]
1080 /// # #![feature(cfg_target_has_reliable_f16_f128)]
1081 /// # #![expect(internal_features)]
1082 /// # #[cfg(not(miri))]
1083 /// # #[cfg(target_has_reliable_f128_math)] {
1084 /// /// The error function relates what percent of a normal distribution lies
1085 /// /// within `x` standard deviations (scaled by `1/sqrt(2)`).
1086 /// fn within_standard_deviations(x: f128) -> f128 {
1087 /// (x * std::f128::consts::FRAC_1_SQRT_2).erf() * 100.0
1088 /// }
1089 ///
1090 /// // 68% of a normal distribution is within one standard deviation
1091 /// assert!((within_standard_deviations(1.0) - 68.269).abs() < 0.01);
1092 /// // 95% of a normal distribution is within two standard deviations
1093 /// assert!((within_standard_deviations(2.0) - 95.450).abs() < 0.01);
1094 /// // 99.7% of a normal distribution is within three standard deviations
1095 /// assert!((within_standard_deviations(3.0) - 99.730).abs() < 0.01);
1096 /// # }
1097 /// ```
1098 #[rustc_allow_incoherent_impl]
1099 #[must_use = "method returns a new number and does not mutate the original value"]
1100 #[unstable(feature = "f128", issue = "116909")]
1101 // #[unstable(feature = "float_erf", issue = "136321")]
1102 #[inline]
1103 pub fn erf(self) -> f128 {
1104 cmath::erff128(self)
1105 }
1106
1107 /// Complementary error function.
1108 ///
1109 /// # Unspecified precision
1110 ///
1111 /// The precision of this function is non-deterministic. This means it varies by platform,
1112 /// Rust version, and can even differ within the same execution from one invocation to the next.
1113 ///
1114 /// This function currently corresponds to the `erfcf128` from libc on Unix
1115 /// and Windows. Note that this might change in the future.
1116 ///
1117 /// # Examples
1118 ///
1119 /// ```
1120 /// #![feature(f128)]
1121 /// #![feature(float_erf)]
1122 /// # #![feature(cfg_target_has_reliable_f16_f128)]
1123 /// # #![expect(internal_features)]
1124 /// # #[cfg(not(miri))]
1125 /// # #[cfg(target_has_reliable_f128_math)] {
1126 /// let x: f128 = 0.123;
1127 ///
1128 /// let one = x.erf() + x.erfc();
1129 /// let abs_difference = (one - 1.0).abs();
1130 ///
1131 /// assert!(abs_difference <= f128::EPSILON);
1132 /// # }
1133 /// ```
1134 #[rustc_allow_incoherent_impl]
1135 #[must_use = "method returns a new number and does not mutate the original value"]
1136 #[unstable(feature = "f128", issue = "116909")]
1137 // #[unstable(feature = "float_erf", issue = "136321")]
1138 #[inline]
1139 pub fn erfc(self) -> f128 {
1140 cmath::erfcf128(self)
1141 }
1142}