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