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